home *** CD-ROM | disk | FTP | other *** search
/ Acorn RISC PD-CD 1 / Acorn RISC PD-CD 1.iso / languages / dde / _pascals / p / pascals
Encoding:
Text File  |  1992-02-27  |  93.2 KB  |  3,419 lines

  1. PROGRAM PASCALS(INPUT , OUTPUT);
  2.  
  3.   LABEL
  4.     99;
  5.  
  6.   CONST
  7.     MAXKEYWORDS = 27;
  8.     ALPHALENGTH = 10;
  9.     LINELENGTH = 120;
  10.     EMAX = 322;
  11.     EMIN = - 99;
  12.     KMAX = 15;
  13.     TMAX = 100;
  14.     BMAX = 20;
  15.     AMAX = 30;
  16.     C2MAX = 20;
  17.     CSMAX = 30;
  18.     CMAX = 850;
  19.     LMAX = 7;
  20.     SMAX = 600;
  21.     ERMAX = 58;
  22.     OMAX = 63;
  23.     XMAX = 131071;
  24.     NMAX = MAXINT;
  25.     LINELENG = 136;
  26.     LINELIMIT = 200;
  27.     STACKSIZE = 1500;
  28.  
  29.   TYPE
  30.     SYMBOL = (INTCON, REALCON, CHARCON, STRING, NOTSY, PLUS, MINUS, TIMES, IDIV,
  31.               RDIV, IMOD, ANDSY, ORSY, EQL, NEQ, GTR, GEQ, LSS, LEQ, LPARENT,
  32.               RPARENT, LBRACK, RBRACK, COMMA, SEMICOLON, PERIOD, COLON, BECOMES,
  33.               CONSTSY, TYPESY, VARSY, FUNCTIONSY, PROCEDURESY, ARRAYSY, RECORDSY
  34.               , PROGRAMSY, IDENT, BEGINSY, IFSY, CASESY, REPEATSY, WHILESY,
  35.               FORSY, ENDSY, ELSESY, UNTILSY, OFSY, DOSY, TOSY, DOWNTOSY, THENSY)
  36.       ;
  37.     INDEX = - XMAX .. + XMAX;
  38.     ALFA = PACKED ARRAY [1.. ALPHALENGTH] OF CHAR;
  39.     OBJECT = (KONSTANT, VARIABLE, TYPE1, PROZEDURE, FUNKTION);
  40.     TYPES = (NOTYP, INTS, REALS, BOOLS, CHARS, ARRAYS, RECORDS);
  41.     SYMSET = SET OF SYMBOL;
  42.     TYPSET = SET OF TYPES;
  43.     ITEM = RECORD
  44.                     TYP: TYPES;
  45.                     IREF: INDEX
  46.            END;
  47.     ORDER = RECORD
  48.                        F: 0 .. + OMAX;
  49.                        X: 0 .. + LMAX;
  50.                        Y: - NMAX .. + NMAX
  51.             END;
  52.  
  53.   VAR
  54.     SY: SYMBOL;
  55.     ID: ALFA;
  56.     INUM: INTEGER;
  57.     RNUM: REAL;
  58.     SLENG: INTEGER;
  59.     CH: CHAR;
  60.     LINE: ARRAY [1 .. LINELENGTH] OF CHAR;
  61.     CC: INTEGER;
  62.     LC: INTEGER;
  63.     LL: INTEGER;
  64.     ERRS: SET OF 0 .. ERMAX;
  65.     ERRPOS: INTEGER;
  66.     PROGNAME: ALFA;
  67.     IFLAG: BOOLEAN;
  68.     OFLAG: BOOLEAN;
  69.     CONSTBEGSYS, TYPEBEGSYS, BLOCKBEGSYS, FACBEGSYS, STATBEGSYS: SYMSET;
  70.     KEY: ARRAY [1 .. MAXKEYWORDS] OF ALFA;
  71.     KSY: ARRAY [1 .. MAXKEYWORDS] OF SYMBOL;
  72.     SPS: ARRAY [CHAR] OF SYMBOL;
  73.     T, A, B, SX, C1, C2: INTEGER;
  74.     STANTYPS: TYPSET;
  75.     DISPLAY: ARRAY [0 .. LMAX] OF INTEGER;
  76.     TAB: ARRAY [0 .. TMAX] OF PACKED RECORD
  77.                                              NAME: ALFA;
  78.                                              LINK: INDEX;
  79.                                               OBJ: OBJECT;
  80.                                               TYP: TYPES;
  81.                                               IREF: INDEX;
  82.                                            NORMAL: BOOLEAN;
  83.                                               LEV: 0 .. LMAX;
  84.                                               ADR: INTEGER
  85.                                      END;
  86.     ATAB: ARRAY [1 .. AMAX] OF PACKED RECORD
  87.                                             INXTYP,
  88.                                              ELTYP: TYPES;
  89.                                              ELIREF,
  90.                                                LOW,
  91.                                               HIGH,
  92.                                             ELSIZE,
  93.                                               SIZE: INDEX;
  94.                                       END;
  95.     BTAB: ARRAY [1 .. BMAX] OF PACKED RECORD
  96.                                               LAST,
  97.                                            LASTPAR,
  98.                                              PSIZE,
  99.                                              VSIZE: INDEX
  100.                                       END;
  101.     STAB: PACKED ARRAY [0 .. SMAX] OF CHAR;
  102.     RCONST: ARRAY [1 .. C2MAX] OF REAL;
  103.     CODE: ARRAY [0 .. CMAX] OF ORDER;
  104.  
  105.  
  106.   PROCEDURE ERRORMSG;
  107.  
  108.     VAR
  109.       K: INTEGER;
  110.       MSG: ARRAY [0 .. ERMAX] OF ALFA;
  111.  
  112.     BEGIN
  113.       MSG[0] := 'UNDEF ID  ';
  114.       MSG[1] := 'MULTI DEF ';
  115.       MSG[2] := 'IDENTIFIER';
  116.       MSG[3] := 'PROGRAM   ';
  117.       MSG[4] := ')         ';
  118.       MSG[5] := ':         ';
  119.       MSG[6] := 'SYNTAX    ';
  120.       MSG[7] := 'IDENT, VAR';
  121.       MSG[8] := 'OF        ';
  122.       MSG[9] := '(         ';
  123.       MSG[10] := 'ID, ARRAY ';
  124.       MSG[11] := '[         ';
  125.       MSG[12] := ']         ';
  126.       MSG[13] := '..        ';
  127.       MSG[14] := ';         ';
  128.       MSG[15] := 'FUNC. TYPE';
  129.       MSG[16] := '=         ';
  130.       MSG[17] := 'BOOLEAN   ';
  131.       MSG[18] := 'CONVAR TYP';
  132.       MSG[19] := 'TYPE      ';
  133.       MSG[20] := 'PROG.PARAM';
  134.       MSG[21] := 'TOO BIG   ';
  135.       MSG[22] := '.         ';
  136.       MSG[23] := 'TYP (CASE)';
  137.       MSG[24] := 'CHARACTER ';
  138.       MSG[25] := 'CONST ID  ';
  139.       MSG[26] := 'INDEX TYPE';
  140.       MSG[27] := 'INDEXBOUND';
  141.       MSG[28] := 'NO ARRAY  ';
  142.       MSG[29] := 'TYPE ID   ';
  143.       MSG[30] := 'UNDEF TYPE';
  144.       MSG[31] := 'NO RECORD ';
  145.       MSG[32] := 'BOOLE TYPE';
  146.       MSG[33] := 'ARITH TYPE';
  147.       MSG[34] := 'INTEGER   ';
  148.       MSG[35] := 'TYPES     ';
  149.       MSG[36] := 'PARAM TYPE';
  150.       MSG[37] := 'VARIAB TYP';
  151.       MSG[38] := 'STRING    ';
  152.       MSG[39] := 'NO.OF PARS';
  153.       MSG[40] := 'TYPE      ';
  154.       MSG[41] := 'TYPE      ';
  155.       MSG[42] := 'REAL TYPE ';
  156.       MSG[43] := 'INTEGER   ';
  157.       MSG[44] := 'VAR, CONST';
  158.       MSG[45] := 'VAR, PROC ';
  159.       MSG[46] := 'TYPES (:=)';
  160.       MSG[47] := 'TYP (CASE)';
  161.       MSG[48] := 'TYPE      ';
  162.       MSG[49] := 'STORE OVFL';
  163.       MSG[50] := 'CONSTANT  ';
  164.       MSG[51] := ':=        ';
  165.       MSG[52] := 'THEN      ';
  166.       MSG[53] := 'UNTIL     ';
  167.       MSG[54] := 'DO        ';
  168.       MSG[55] := 'TO DOWNTO ';
  169.       MSG[56] := 'BEGIN     ';
  170.       MSG[57] := 'END       ';
  171.       MSG[58] := 'FACTOR    ';
  172.       K := 0;
  173.       WRITELN;
  174.       WRITELN(' KEY WORDS');
  175.       WHILE ERRS <> [] DO
  176.         BEGIN
  177.           WHILE NOT (K IN ERRS) DO
  178.             K := K + 1;
  179.           WRITELN(K, '  ', MSG[K]);
  180.           ERRS := ERRS - [K]
  181.         END (*WHILE*)
  182.     END (*ERRORMSG*);
  183.  
  184.  
  185.   PROCEDURE NEXTCH;
  186. (* READ THE NEXT CHARACTER AND THE END OF LINES *)
  187.  
  188.     BEGIN
  189.       IF CC = LL
  190.       THEN
  191.         BEGIN
  192.           IF EOF(INPUT) THEN
  193.             BEGIN
  194.               WRITELN;
  195.               WRITELN(' PROGRAM INCOMPLETE.');
  196.               ERRORMSG;
  197.               GOTO 99
  198.             END (*IF*);
  199.           IF ERRPOS <> 0 THEN
  200.             BEGIN
  201.               WRITELN;
  202.               ERRPOS := 0
  203.             END (*IF*);
  204.           WRITE(LC: 5, '  ');
  205.           LL := 0;
  206.           CC := 0;
  207.           WHILE NOT EOLN(INPUT) DO
  208.             BEGIN
  209.               LL := LL + 1;
  210.               READ(CH);
  211.               WRITE(CH);
  212.               LINE[LL] := CH
  213.             END (*WHILE*);
  214.           WRITELN;
  215.           LL := LL + 1;
  216.           READ(LINE[LL])
  217.         END (*IF*);
  218.       CC := CC + 1;
  219.       CH := LINE[CC]
  220.     END (*NEXTCH*);
  221.  
  222.  
  223.   PROCEDURE ERROR(N: INTEGER);
  224.  
  225.     BEGIN
  226.       IF ERRPOS = 0 THEN
  227.         WRITE(' ****');
  228.       IF CC > ERRPOS THEN
  229.         BEGIN
  230.           WRITE(' ': CC - ERRPOS, '@', N: 2);
  231.           ERRPOS := CC + 3;
  232.           ERRS := ERRS + [N]
  233.         END (*IF*)
  234.     END (*ERROR*);
  235.  
  236.  
  237.   PROCEDURE FATAL(N: INTEGER);
  238.  
  239.     VAR
  240.       MSG: ARRAY [1 .. 7] OF ALFA;
  241.  
  242.     BEGIN
  243.       WRITELN;
  244.       ERRORMSG;
  245.       MSG[1] := 'IDENTIFIER';
  246.       MSG[2] := 'PROCEDURES';
  247.       MSG[3] := 'REALS     ';
  248.       MSG[4] := 'ARRAYS    ';
  249.       MSG[5] := 'LEVELS    ';
  250.       MSG[6] := 'CODE      ';
  251.       MSG[7] := 'STRINGS   ';
  252.       WRITELN(' COMPILER TABLE FOR ', MSG[N], ' IS TOO SMALL');
  253.       GOTO 99 (* TERMINATE COMPILATION *);
  254.     END (*FATAL*);
  255.  
  256.  
  257.   PROCEDURE INSYMBOL;
  258. (* READS NEXT SYMBOL *)
  259.  
  260.     LABEL
  261.       1, 2, 3;
  262.  
  263.     VAR
  264.       I, J, K, E: INTEGER;
  265.  
  266.  
  267.     PROCEDURE READSCALE;
  268.  
  269.       VAR
  270.         S, SIGN: INTEGER;
  271.  
  272.       BEGIN
  273.         NEXTCH;
  274.         SIGN := 1;
  275.         S := 0;
  276.         IF CH = '+'
  277.         THEN
  278.           NEXTCH
  279.         ELSE
  280.           IF CH = '-' THEN
  281.             BEGIN
  282.               NEXTCH;
  283.               SIGN := - 1;
  284.             END (*IF*);
  285.         WHILE CH IN ['0' .. '9'] DO
  286.           BEGIN
  287.             S := 10 * S + ORD(CH) - ORD('0');
  288.             NEXTCH
  289.           END (*WHILE*);
  290.         E := S * SIGN + E
  291.       END (*READSCALE*);
  292.  
  293.  
  294.     PROCEDURE ADJUSTSCALE;
  295.  
  296.       VAR
  297.         S: INTEGER;
  298.         D, T: REAL;
  299.  
  300.       BEGIN
  301.         IF K + E > EMAX
  302.         THEN
  303.           ERROR(21)
  304.         ELSE
  305.           IF K + E < EMIN
  306.           THEN
  307.             RNUM := 0
  308.           ELSE
  309.             BEGIN
  310.               S := ABS(E);
  311.               T := 1.0;
  312.               D := 10.0;
  313.               REPEAT
  314.                 WHILE NOT ODD(S) DO
  315.                   BEGIN
  316.                     S := S DIV 2;
  317.                     D := SQR(D)
  318.                   END (*WHILE*);
  319.                 S := S - 1;
  320.                 T := D * T
  321.               UNTIL S = 0;
  322.               IF E >= 0
  323.               THEN
  324.                 RNUM := RNUM * T
  325.               ELSE
  326.                 RNUM := RNUM / T
  327.             END (*ELSE*)
  328.       END (*ADJUSTSCALE*);
  329.  
  330.  
  331.     BEGIN (*INSYMBOL*)
  332.    1: WHILE CH = ' ' DO
  333.         NEXTCH;
  334.       IF CH IN ['A' .. 'Z']
  335.       THEN
  336.         BEGIN (*WORD*)
  337.           K := 0;
  338.           ID := '          ';
  339.           REPEAT
  340.             IF K < ALPHALENGTH THEN
  341.               BEGIN
  342.                 K := K + 1;
  343.                 ID[K] := CH
  344.               END (*IF*);
  345.             NEXTCH
  346.           UNTIL NOT (CH IN ['A' .. 'Z', '0' .. '9']);
  347.           I := 1;
  348.           J := MAXKEYWORDS;
  349. (* BINARY SEARCH *)
  350.           REPEAT
  351.             K := (I + J) DIV 2;
  352.             IF ID <= KEY[K] THEN
  353.               J := K - 1;
  354.             IF ID >= KEY[K] THEN
  355.               I := K + 1
  356.           UNTIL I > J;
  357.           IF I - 1 > J
  358.           THEN
  359.             SY := KSY[K]
  360.           ELSE
  361.             SY := IDENT
  362.         END (*IF*)
  363.       ELSE
  364.         IF CH IN ['0' .. '9']
  365.         THEN
  366.           BEGIN (* NUMBER *)
  367.             K := 0;
  368.             INUM := 0;
  369.             SY := INTCON;
  370.             REPEAT
  371.               INUM := INUM * 10 + ORD(CH) - ORD('0');
  372.               K := K + 1;
  373.               NEXTCH
  374.             UNTIL NOT (CH IN ['0' .. '9']);
  375.             IF (K > KMAX) OR (INUM > NMAX) THEN
  376.               BEGIN
  377.                 ERROR(21);
  378.                 INUM := 0;
  379.                 K := 0
  380.               END (*IF*);
  381.             IF CH = '.'
  382.             THEN
  383.               BEGIN
  384.                 NEXTCH;
  385.                 IF CH = '.'
  386.                 THEN
  387.                   CH := ':'
  388.                 ELSE
  389.                   BEGIN
  390.                     SY := REALCON;
  391.                     RNUM := INUM;
  392.                     E := 0;
  393.                     WHILE CH IN ['0' .. '9'] DO
  394.                       BEGIN
  395.                         E := E - 1;
  396.                         RNUM := 10.0 * RNUM + (ORD(CH) - ORD('0'));
  397.                         NEXTCH
  398.                       END (*WHILE*);
  399.                     IF CH = 'E' THEN
  400.                       READSCALE;
  401.                     IF E <> 0 THEN
  402.                       ADJUSTSCALE
  403.                   END (*ELSE*)
  404.               END (*IF*)
  405.             ELSE
  406.               IF CH = 'E' THEN
  407.                 BEGIN
  408.                   SY := REALCON;
  409.                   RNUM := INUM;
  410.                   E := 0;
  411.                   READSCALE;
  412.                   IF E <> 0 THEN
  413.                     ADJUSTSCALE
  414.                 END (*IF*)
  415.           END (*IF*)
  416.         ELSE
  417.           CASE CH OF
  418.             ':':
  419.               BEGIN
  420.                 NEXTCH;
  421.                 IF CH = '='
  422.                 THEN
  423.                   BEGIN
  424.                     SY := BECOMES;
  425.                     NEXTCH
  426.                   END (*IF*)
  427.                 ELSE
  428.                   SY := COLON
  429.               END (*':'*);
  430.             '<':
  431.               BEGIN
  432.                 NEXTCH;
  433.                 IF CH = '='
  434.                 THEN
  435.                   BEGIN
  436.                     SY := LEQ;
  437.                     NEXTCH
  438.                   END (*IF*)
  439.                 ELSE
  440.                   IF CH = '>'
  441.                   THEN
  442.                     BEGIN
  443.                       SY := NEQ;
  444.                       NEXTCH
  445.                     END (*IF*)
  446.                   ELSE
  447.                     SY := LSS
  448.               END (*'<'*);
  449.             '>':
  450.               BEGIN
  451.                 NEXTCH;
  452.                 IF CH = '='
  453.                 THEN
  454.                   BEGIN
  455.                     SY := GEQ;
  456.                     NEXTCH
  457.                   END (*IF*)
  458.                 ELSE
  459.                   SY := GTR
  460.               END (*'>'*);
  461.             '.':
  462.               BEGIN
  463.                 NEXTCH;
  464.                 IF CH = '.'
  465.                 THEN
  466.                   BEGIN
  467.                     SY := COLON;
  468.                     NEXTCH
  469.                   END (*IF*)
  470.                 ELSE
  471.                   SY := PERIOD
  472.               END (*'.'*);
  473.             '''':
  474.               BEGIN
  475.                 K := 0;
  476.              2: NEXTCH;
  477.                 IF CH = '''' THEN
  478.                   BEGIN
  479.                     NEXTCH;
  480.                     IF CH <> '''' THEN
  481.                       GOTO 3
  482.                   END (*IF*);
  483.                 IF SX + K = SMAX THEN
  484.                   FATAL(7);
  485.                 STAB[SX + K] := CH;
  486.                 K := K + 1;
  487.                 IF CC = 1
  488.                 THEN
  489.                   BEGIN (* END OF LINE *)
  490.                     K := 0
  491.                   END (*IF*)
  492.                 ELSE
  493.                   GOTO 2;
  494.              3: IF K = 1
  495.                 THEN
  496.                   BEGIN
  497.                     SY := CHARCON;
  498.                     INUM := ORD(STAB[SX])
  499.                   END (*IF*)
  500.                 ELSE
  501.                   IF K = 0
  502.                   THEN
  503.                     BEGIN
  504.                       ERROR(38);
  505.                       SY := CHARCON;
  506.                       INUM := 0
  507.                     END (*IF*)
  508.                   ELSE
  509.                     BEGIN
  510.                       SY := STRING;
  511.                       INUM := SX;
  512.                       SLENG := K;
  513.                       SX := SX + K
  514.                     END (*ELSE*)
  515.               END (*''''*);
  516.             '(':
  517.               BEGIN
  518.                 NEXTCH;
  519.                 IF CH <> '*'
  520.                 THEN
  521.                   SY := LPARENT
  522.                 ELSE
  523.                   BEGIN (* COMMENT *)
  524.                     REPEAT
  525.                       WHILE CH <> '*' DO
  526.                         NEXTCH;
  527.                       NEXTCH;
  528.                     UNTIL CH = ')';
  529.                     NEXTCH;
  530.                     GOTO 1
  531.                   END (*ELSE*)
  532.               END (*'('*);
  533.             '+', '-', '*', '/', ')', '=', ',', '[', ']', '#', '&', ';':
  534.               BEGIN
  535.                 SY := SPS[CH];
  536.                 NEXTCH
  537.               END (*'+'*);
  538.             '\', '%', '@', '$', '!':
  539.               BEGIN
  540.                 ERROR(24);
  541.                 NEXTCH;
  542.                 GOTO 1
  543.               END (*'\'*)
  544.           END (*CASE*)
  545.     END (*INSYMBOL*);
  546.  
  547.  
  548.   PROCEDURE ENTER(X0: ALFA; X1: OBJECT; X2: TYPES; X3: INTEGER);
  549.  
  550.     BEGIN (* ENTER STANDARD IDENTIFIER *)
  551.       T := T + 1;
  552.       WITH TAB[T] DO
  553.         BEGIN
  554.           NAME := X0;
  555.           LINK := T - 1;
  556.           OBJ := X1;
  557.           TYP := X2;
  558.           IREF := 0;
  559.           NORMAL := TRUE;
  560.           LEV := 0;
  561.           ADR := X3
  562.         END (*WITH*)
  563.     END (*ENTER*);
  564.  
  565.  
  566.   PROCEDURE ENTERARRAY(TP: TYPES; L, H: INTEGER);
  567.  
  568.     BEGIN
  569.       IF L > H THEN
  570.         ERROR(27);
  571.       IF (ABS(L) > XMAX) OR (ABS(H) > XMAX) THEN
  572.         BEGIN
  573.           ERROR(27);
  574.           L := 0;
  575.           H := 0
  576.         END (*IF*);
  577.       IF A = AMAX
  578.       THEN
  579.         FATAL(4)
  580.       ELSE
  581.         BEGIN
  582.           A := A + 1;
  583.           WITH ATAB[A] DO
  584.             BEGIN
  585.               INXTYP := TP;
  586.               LOW := L;
  587.               HIGH := H
  588.             END (*WITH*)
  589.         END (*ELSE*)
  590.     END (*ENTERARRAY*);
  591.  
  592.  
  593.   PROCEDURE ENTERBLOCK;
  594.  
  595.     BEGIN
  596.       IF B = BMAX
  597.       THEN
  598.         FATAL(2)
  599.       ELSE
  600.         BEGIN
  601.           B := B + 1;
  602.           BTAB[B].LAST := 0;
  603.           BTAB[B].LASTPAR := 0;
  604.         END (*ELSE*)
  605.     END (*ENTERBLOCK*);
  606.  
  607.  
  608.   PROCEDURE ENTERREAL(X: REAL);
  609.  
  610.     BEGIN
  611.       IF C2 = C2MAX - 1
  612.       THEN
  613.         FATAL(3)
  614.       ELSE
  615.         BEGIN
  616.           RCONST[C2 + 1] := X;
  617.           C1 := 1;
  618.           WHILE RCONST[C1] <> X DO
  619.             C1 := C1 + 1;
  620.           IF C1 > C2 THEN
  621.             C2 := C1
  622.         END (*ELSE*)
  623.     END (*ENTERREAL*);
  624.  
  625.  
  626.   PROCEDURE EMIT(FCT: INTEGER);
  627.  
  628.     BEGIN
  629.       IF LC = CMAX THEN
  630.         FATAL(6);
  631.       CODE[LC].F := FCT;
  632.       LC := LC + 1
  633.     END (*EMIT*);
  634.  
  635.  
  636.   PROCEDURE EMIT1(FCT, B: INTEGER);
  637.  
  638.     BEGIN
  639.       IF LC = CMAX THEN
  640.         FATAL(6);
  641.       WITH CODE[LC] DO
  642.         BEGIN
  643.           F := FCT;
  644.           Y := B
  645.         END (*WITH*);
  646.       LC := LC + 1
  647.     END (*EMIT1*);
  648.  
  649.  
  650.   PROCEDURE EMIT2(FCT, A, B: INTEGER);
  651.  
  652.     BEGIN
  653.       IF LC = CMAX THEN
  654.         FATAL(6);
  655.       WITH CODE[LC] DO
  656.         BEGIN
  657.           F := FCT;
  658.           X := A;
  659.           Y := B
  660.         END (*WITH*);
  661.       LC := LC + 1
  662.     END (*EMIT2*);
  663.  
  664.  
  665.   PROCEDURE PRINTTABLES;
  666.  
  667.     VAR
  668.       I: INTEGER;
  669.       O: ORDER;
  670.  
  671.     BEGIN
  672.       WRITELN('0IDENTIFIERS      LINK  OBJ  TYP  IREF  NRM  LEV  ADR');
  673.       FOR I := BTAB[1].LAST + 1 TO T DO
  674.         WITH TAB[I] DO
  675.           WRITELN(I, ' ', NAME, LINK: 5, ORD(OBJ): 5, ORD(TYP): 5, IREF: 5, ORD(
  676.             NORMAL): 5, LEV: 5, ADR: 5);
  677.       WRITELN('0BLOCKS    LAST LPAR PSZE VSZE');
  678.       FOR I := 1 TO B DO
  679.         WITH BTAB[I] DO
  680.           WRITELN(I, LAST: 5, LASTPAR: 5, PSIZE: 5, VSIZE: 5);
  681.       WRITELN('0ARRAYS    XTYP ETYP EIREF  LOW HIGH ELSZ SIZE');
  682.       FOR I := 1 TO A DO
  683.         WITH ATAB[I] DO
  684.           WRITELN(I, ORD(INXTYP): 5, ORD(ELTYP): 5, ELIREF: 5, LOW: 5, HIGH: 5,
  685.             ELSIZE: 5, SIZE: 5);
  686.       WRITELN('0CODE');
  687.       FOR I := 0 TO LC - 1 DO
  688.         BEGIN
  689.           IF I MOD 5 = 0 THEN
  690.             BEGIN
  691.               WRITELN;
  692.               WRITE(I: 5)
  693.             END (*IF*);
  694.           O := CODE[I];
  695.           WRITE(O.F: 5);
  696.           IF O.F < 31
  697.           THEN
  698.             IF O.F < 4
  699.             THEN
  700.               WRITE(O.X: 2, O.Y: 5)
  701.             ELSE
  702.               WRITE(O.Y: 7)
  703.           ELSE
  704.             WRITE('        ');
  705.           WRITE(',')
  706.         END (*FOR*);
  707.       WRITELN;
  708.     END (*PRINTTABLES*);
  709.  
  710.  
  711.   PROCEDURE BLOCK(FSYS: SYMSET; ISFUN: BOOLEAN; LEVEL: INTEGER);
  712.  
  713.     TYPE
  714.       CONREC = RECORD
  715.                     CASE TP: TYPES OF
  716.                    INTS, CHARS, BOOLS: (         I: INTEGER);
  717.                    REALS: (         R: REAL)
  718.                END;
  719.  
  720.     VAR
  721.       DX, (* DATA ALLOCATION INDEX *)
  722.       PRT, (* T-INDEX OF THIS PROCEDURE *)
  723.       PRB, (* B-INDEX OF THIS PROCEDURE *)
  724.       X: INTEGER;
  725.  
  726.  
  727.     PROCEDURE SKIP(FSYS: SYMSET; N: INTEGER);
  728.  
  729.       BEGIN
  730.         ERROR(N);
  731.         WHILE NOT (SY IN FSYS) DO
  732.           INSYMBOL
  733.       END (*SKIP*);
  734.  
  735.  
  736.     PROCEDURE TEST(S1, S2: SYMSET; N: INTEGER);
  737.  
  738.       BEGIN
  739.         IF NOT (SY IN S1) THEN
  740.           SKIP(S1 + S2, N)
  741.       END (*TEST*);
  742.  
  743.  
  744.     PROCEDURE TESTSEMICOLON;
  745.  
  746.       BEGIN
  747.         IF SY = SEMICOLON
  748.         THEN
  749.           INSYMBOL
  750.         ELSE
  751.           BEGIN
  752.             ERROR(14);
  753.             IF SY IN [COMMA, COLON] THEN
  754.               INSYMBOL
  755.           END (*ELSE*);
  756.         TEST([IDENT] + BLOCKBEGSYS, FSYS, 6)
  757.       END (*TESTSEMICOLON*);
  758.  
  759.  
  760.     PROCEDURE ENTER(ID: ALFA; K: OBJECT);
  761.  
  762.       VAR
  763.         J, L: INTEGER;
  764.  
  765.       BEGIN
  766.         IF T = TMAX
  767.         THEN
  768.           FATAL(1)
  769.         ELSE
  770.           BEGIN
  771.             TAB[0].NAME := ID;
  772.             J := BTAB[DISPLAY[LEVEL]].LAST;
  773.             L := J;
  774.             WHILE TAB[J].NAME <> ID DO
  775.               J := TAB[J].LINK;
  776.             IF J <> 0
  777.             THEN
  778.               ERROR(1)
  779.             ELSE
  780.               BEGIN
  781.                 T := T + 1;
  782.                 WITH TAB[T] DO
  783.                   BEGIN
  784.                     NAME := ID;
  785.                     LINK := L;
  786.                     OBJ := K;
  787.                     TYP := NOTYP;
  788.                     IREF := 0;
  789.                     LEV := LEVEL;
  790.                     ADR := 0
  791.                   END (*WITH*);
  792.                 BTAB[DISPLAY[LEVEL]].LAST := T
  793.               END (*ELSE*)
  794.           END (*ELSE*)
  795.       END (*ENTER*);
  796.  
  797.  
  798.     FUNCTION LOC(ID: ALFA): INTEGER;
  799.  
  800.       VAR
  801.         I, J: INTEGER;
  802. (* LOCATE ID IN TABLE *)
  803.  
  804.       BEGIN
  805.         I := LEVEL;
  806.         TAB[0].NAME := ID;
  807.         REPEAT
  808.           J := BTAB[DISPLAY[I]].LAST;
  809.           WHILE TAB[J].NAME <> ID DO
  810.             J := TAB[J].LINK;
  811.           I := I - 1
  812.         UNTIL (I < 0) OR (J <> 0);
  813.         IF J = 0 THEN
  814.           ERROR(0);
  815.         LOC := J
  816.       END (*LOC*);
  817.  
  818.  
  819.     PROCEDURE ENTERVARIABLE;
  820.  
  821.       BEGIN
  822.         IF SY = IDENT
  823.         THEN
  824.           BEGIN
  825.             ENTER(ID, VARIABLE);
  826.             INSYMBOL
  827.           END (*IF*)
  828.         ELSE
  829.           ERROR(2)
  830.       END (*ENTERVARIABLE*);
  831.  
  832.  
  833.     PROCEDURE CONSTANT(FSYS: SYMSET; VAR C: CONREC);
  834.  
  835.       VAR
  836.         X, SIGN: INTEGER;
  837.  
  838.       BEGIN
  839.         C.TP := NOTYP;
  840.         C.I := 0;
  841.         TEST(CONSTBEGSYS, FSYS, 50);
  842.         IF SY IN CONSTBEGSYS
  843.         THEN
  844.           BEGIN
  845.             IF SY = CHARCON
  846.             THEN
  847.               BEGIN
  848.                 C.TP := CHARS;
  849.                 C.I := INUM;
  850.                 INSYMBOL
  851.               END (*IF*)
  852.             ELSE
  853.               BEGIN
  854.                 SIGN := 1;
  855.                 IF SY IN [PLUS, MINUS] THEN
  856.                   BEGIN
  857.                     IF SY = MINUS THEN
  858.                       SIGN := - 1;
  859.                     INSYMBOL
  860.                   END (*IF*);
  861.                 IF SY = IDENT
  862.                 THEN
  863.                   BEGIN
  864.                     X := LOC(ID);
  865.                     IF X <> 0
  866.                     THEN
  867.                       IF TAB[X].OBJ <> KONSTANT
  868.                       THEN
  869.                         ERROR(25)
  870.                       ELSE
  871.                         BEGIN
  872.                           C.TP := TAB[X].TYP;
  873.                           IF C.TP = REALS
  874.                           THEN
  875.                             C.R := SIGN * RCONST[TAB[X].ADR]
  876.                           ELSE
  877.                             C.I := SIGN * TAB[X].ADR
  878.                         END (*ELSE*);
  879.                     INSYMBOL
  880.                   END (*IF*)
  881.                 ELSE
  882.                   IF SY = INTCON
  883.                   THEN
  884.                     BEGIN
  885.                       C.TP := INTS;
  886.                       C.I := SIGN * INUM;
  887.                       INSYMBOL
  888.                     END (*IF*)
  889.                   ELSE
  890.                     IF SY = REALCON
  891.                     THEN
  892.                       BEGIN
  893.                         C.TP := REALS;
  894.                         C.R := SIGN * RNUM;
  895.                         INSYMBOL
  896.                       END (*IF*)
  897.                     ELSE
  898.                       SKIP(FSYS, 50)
  899.               END (*ELSE*);
  900.             TEST(FSYS, [], 6)
  901.           END (*IF*)
  902.       END (*CONSTANT*);
  903.  
  904.  
  905.     PROCEDURE TYP(FSYS: SYMSET; VAR TP: TYPES; VAR RF, SZ: INTEGER);
  906.  
  907.       VAR
  908.         X: INTEGER;
  909.         ELTP: TYPES;
  910.         ELRF: INTEGER;
  911.         ELSZ, OFFSET, T0, T1: INTEGER;
  912.  
  913.  
  914.       PROCEDURE ARRAYTYP(VAR AIREF, ARSZ: INTEGER);
  915.  
  916.         VAR
  917.           ELTP: TYPES;
  918.           LOW, HIGH: CONREC;
  919.           ELRF, ELSZ: INTEGER;
  920.  
  921.         BEGIN
  922.           CONSTANT([COLON, RBRACK, RPARENT, OFSY] + FSYS, LOW);
  923.           IF LOW.TP = REALS THEN
  924.             BEGIN
  925.               ERROR(27);
  926.               LOW.TP := INTS;
  927.               LOW.I := 0
  928.             END (*IF*);
  929.           IF SY = COLON
  930.           THEN
  931.             INSYMBOL
  932.           ELSE
  933.             ERROR(13);
  934.           CONSTANT([RBRACK, COMMA, RPARENT, OFSY] + FSYS, HIGH);
  935.           IF HIGH.TP <> LOW.TP THEN
  936.             BEGIN
  937.               ERROR(27);
  938.               HIGH.I := LOW.I
  939.             END (*IF*);
  940.           ENTERARRAY(LOW.TP, LOW.I, HIGH.I);
  941.           AIREF := A;
  942.           IF SY = COMMA
  943.           THEN
  944.             BEGIN
  945.               INSYMBOL;
  946.               ELTP := ARRAYS;
  947.               ARRAYTYP(ELRF, ELSZ)
  948.             END (*IF*)
  949.           ELSE
  950.             BEGIN
  951.               IF SY = RBRACK
  952.               THEN
  953.                 INSYMBOL
  954.               ELSE
  955.                 BEGIN
  956.                   ERROR(12);
  957.                   IF SY = RPARENT THEN
  958.                     INSYMBOL
  959.                 END (*ELSE*);
  960.               IF SY = OFSY
  961.               THEN
  962.                 INSYMBOL
  963.               ELSE
  964.                 ERROR(8);
  965.               TYP(FSYS, ELTP, ELRF, ELSZ)
  966.             END (*ELSE*);
  967.           WITH ATAB[AIREF] DO
  968.             BEGIN
  969.               ARSZ := (HIGH - LOW + 1) * ELSZ;
  970.               SIZE := ARSZ;
  971.               ELTYP := ELTP;
  972.               ELIREF := ELRF;
  973.               ELSIZE := ELSZ
  974.             END (*WITH*)
  975.         END (*ARRAYTYP*);
  976.  
  977.  
  978.       BEGIN (*TYP*)
  979.         TP := NOTYP;
  980.         RF := 0;
  981.         SZ := 0;
  982.         TEST(TYPEBEGSYS, FSYS, 10);
  983.         IF SY IN TYPEBEGSYS
  984.         THEN
  985.           BEGIN
  986.             IF SY = IDENT
  987.             THEN
  988.               BEGIN
  989.                 X := LOC(ID);
  990.                 IF X <> 0 THEN
  991.                   WITH TAB[X] DO
  992.                     IF OBJ <> TYPE1
  993.                     THEN
  994.                       ERROR(29)
  995.                     ELSE
  996.                       BEGIN
  997.                         TP := TYP;
  998.                         RF := IREF;
  999.                         SZ := ADR;
  1000.                         IF TP = NOTYP THEN
  1001.                           ERROR(30)
  1002.                       END (*ELSE*);
  1003.                 INSYMBOL
  1004.               END (*IF*)
  1005.             ELSE
  1006.               IF SY = ARRAYSY
  1007.               THEN
  1008.                 BEGIN
  1009.                   INSYMBOL;
  1010.                   IF SY = LBRACK
  1011.                   THEN
  1012.                     INSYMBOL
  1013.                   ELSE
  1014.                     BEGIN
  1015.                       ERROR(11);
  1016.                       IF SY = LPARENT THEN
  1017.                         INSYMBOL
  1018.                     END (*ELSE*);
  1019.                   TP := ARRAYS;
  1020.                   ARRAYTYP(RF, SZ)
  1021.                 END (*IF*)
  1022.               ELSE
  1023.                 BEGIN (*RECORDS*)
  1024.                   INSYMBOL;
  1025.                   ENTERBLOCK;
  1026.                   TP := RECORDS;
  1027.                   RF := B;
  1028.                   IF LEVEL = LMAX THEN
  1029.                     FATAL(5);
  1030.                   LEVEL := LEVEL + 1;
  1031.                   DISPLAY[LEVEL] := B;
  1032.                   OFFSET := 0;
  1033.                   WHILE SY <> ENDSY DO
  1034.                     BEGIN (* FIELD SECXTION *)
  1035.                       IF SY = IDENT
  1036.                       THEN
  1037.                         BEGIN
  1038.                           T0 := T;
  1039.                           ENTERVARIABLE;
  1040.                           WHILE SY = COMMA DO
  1041.                             BEGIN
  1042.                               INSYMBOL;
  1043.                               ENTERVARIABLE
  1044.                             END (*WHILE*);
  1045.                           IF SY = COLON
  1046.                           THEN
  1047.                             INSYMBOL
  1048.                           ELSE
  1049.                             ERROR(5);
  1050.                           T1 := T;
  1051.                           TYP(FSYS + [SEMICOLON, ENDSY, COMMA, IDENT], ELTP,
  1052.                             ELRF, ELSZ);
  1053.                           WHILE T0 < T1 DO
  1054.                             BEGIN
  1055.                               T0 := T0 + 1;
  1056.                               WITH TAB[T0] DO
  1057.                                 BEGIN
  1058.                                   TYP := ELTP;
  1059.                                   IREF := ELRF;
  1060.                                   NORMAL := TRUE;
  1061.                                   ADR := OFFSET;
  1062.                                   OFFSET := OFFSET + ELSZ
  1063.                                 END (*WITH*)
  1064.                             END (*WHILE*)
  1065.                         END (*IF*);
  1066.                       IF SY <> ENDSY
  1067.                       THEN
  1068.                         BEGIN
  1069.                           IF SY = SEMICOLON
  1070.                           THEN
  1071.                             INSYMBOL
  1072.                           ELSE
  1073.                             BEGIN
  1074.                               ERROR(14);
  1075.                               IF SY = COMMA THEN
  1076.                                 INSYMBOL
  1077.                             END (*ELSE*);
  1078.                           TEST([IDENT, ENDSY, SEMICOLON], FSYS, 6)
  1079.                         END (*IF*);
  1080.                     END (*WHILE*);
  1081.                   BTAB[RF].VSIZE := OFFSET;
  1082.                   SZ := OFFSET;
  1083.                   BTAB[RF].PSIZE := 0;
  1084.                   INSYMBOL;
  1085.                   LEVEL := LEVEL - 1
  1086.                 END (*ELSE*);
  1087.             TEST(FSYS, [], 6)
  1088.           END (*IF*)
  1089.       END (*TYP*);
  1090.  
  1091.  
  1092.     PROCEDURE PARAMETERLIST;
  1093. (* FORMAL PARAMETER LIST *)
  1094.  
  1095.       VAR
  1096.         TP: TYPES;
  1097.         RF, SZ, X, T0: INTEGER;
  1098.         VALPAR: BOOLEAN;
  1099.  
  1100.       BEGIN
  1101.         INSYMBOL;
  1102.         TP := NOTYP;
  1103.         RF := 0;
  1104.         SZ := 0;
  1105.         TEST([IDENT, VARSY], FSYS + [RPARENT], 7);
  1106.         WHILE SY IN [IDENT, VARSY] DO
  1107.           BEGIN
  1108.             IF SY <> VARSY
  1109.             THEN
  1110.               VALPAR := TRUE
  1111.             ELSE
  1112.               BEGIN
  1113.                 INSYMBOL;
  1114.                 VALPAR := FALSE
  1115.               END (*ELSE*);
  1116.             T0 := T;
  1117.             ENTERVARIABLE;
  1118.             WHILE SY = COMMA DO
  1119.               BEGIN
  1120.                 INSYMBOL;
  1121.                 ENTERVARIABLE
  1122.               END (*WHILE*);
  1123.             IF SY = COLON
  1124.             THEN
  1125.               BEGIN
  1126.                 INSYMBOL;
  1127.                 IF SY <> IDENT
  1128.                 THEN
  1129.                   ERROR(2)
  1130.                 ELSE
  1131.                   BEGIN
  1132.                     X := LOC(ID);
  1133.                     INSYMBOL;
  1134.                     IF X <> 0 THEN
  1135.                       WITH TAB[X] DO
  1136.                         IF OBJ <> TYPE1
  1137.                         THEN
  1138.                           ERROR(29)
  1139.                         ELSE
  1140.                           BEGIN
  1141.                             TP := TYP;
  1142.                             RF := IREF;
  1143.                             IF VALPAR
  1144.                             THEN
  1145.                               SZ := ADR
  1146.                             ELSE
  1147.                               SZ := 1;
  1148.                           END (*ELSE*);
  1149.                   END (*ELSE*);
  1150.                 TEST([SEMICOLON, RPARENT], [COMMA, IDENT] + FSYS, 14);
  1151.               END (*IF*)
  1152.             ELSE
  1153.               ERROR(5);
  1154.             WHILE T0 < T DO
  1155.               BEGIN
  1156.                 T0 := T0 + 1;
  1157.                 WITH TAB[T0] DO
  1158.                   BEGIN
  1159.                     TYP := TP;
  1160.                     IREF := RF;
  1161.                     NORMAL := VALPAR;
  1162.                     ADR := DX;
  1163.                     LEV := LEVEL;
  1164.                     DX := DX + SZ
  1165.                   END (*WITH*)
  1166.               END (*WHILE*);
  1167.             IF SY <> RPARENT
  1168.             THEN
  1169.               BEGIN
  1170.                 IF SY = SEMICOLON
  1171.                 THEN
  1172.                   INSYMBOL
  1173.                 ELSE
  1174.                   BEGIN
  1175.                     ERROR(14);
  1176.                     IF SY = COMMA THEN
  1177.                       INSYMBOL
  1178.                   END (*ELSE*);
  1179.                 TEST([IDENT, VARSY], [RPARENT] + FSYS, 6)
  1180.               END (*IF*)
  1181.           END (*WHILE*);
  1182.         IF SY = RPARENT
  1183.         THEN
  1184.           BEGIN
  1185.             INSYMBOL;
  1186.             TEST([SEMICOLON, COLON], FSYS, 6)
  1187.           END (*IF*)
  1188.         ELSE
  1189.           ERROR(4)
  1190.       END (*PARAMETERLIST*);
  1191.  
  1192.  
  1193.     PROCEDURE CONSTANTDECLARATION;
  1194.  
  1195.       VAR
  1196.         C: CONREC;
  1197.  
  1198.       BEGIN
  1199.         INSYMBOL;
  1200.         TEST([IDENT], BLOCKBEGSYS, 2);
  1201.         WHILE SY = IDENT DO
  1202.           BEGIN
  1203.             ENTER(ID, KONSTANT);
  1204.             INSYMBOL;
  1205.             IF SY = EQL
  1206.             THEN
  1207.               INSYMBOL
  1208.             ELSE
  1209.               BEGIN
  1210.                 IF SY = BECOMES THEN
  1211.                   INSYMBOL
  1212.               END (*ELSE*);
  1213.             CONSTANT([SEMICOLON, COMMA, IDENT] + FSYS, C);
  1214.             TAB[T].TYP := C.TP;
  1215.             TAB[T].IREF := 0;
  1216.             IF C.TP = REALS
  1217.             THEN
  1218.               BEGIN
  1219.                 ENTERREAL(C.R);
  1220.                 TAB[T].ADR := C1
  1221.               END (*IF*)
  1222.             ELSE
  1223.               TAB[T].ADR := C.I;
  1224.             TESTSEMICOLON
  1225.           END (*WHILE*)
  1226.       END (*CONSTANTDECLARATION*);
  1227.  
  1228.  
  1229.     PROCEDURE TYPEDECLARATION;
  1230.  
  1231.       VAR
  1232.         TP: TYPES;
  1233.         RF, SZ, T1: INTEGER;
  1234.  
  1235.       BEGIN
  1236.         INSYMBOL;
  1237.         TEST([IDENT], BLOCKBEGSYS, 2);
  1238.         WHILE SY = IDENT DO
  1239.           BEGIN
  1240.             ENTER(ID, TYPE1);
  1241.             T1 := T;
  1242.             INSYMBOL;
  1243.             IF SY = EQL
  1244.             THEN
  1245.               INSYMBOL
  1246.             ELSE
  1247.               BEGIN
  1248.                 ERROR(16);
  1249.                 IF SY = BECOMES THEN
  1250.                   INSYMBOL
  1251.               END (*ELSE*);
  1252.             TYP([SEMICOLON, COMMA, IDENT] + FSYS, TP, RF, SZ);
  1253.             WITH TAB[T1] DO
  1254.               BEGIN
  1255.                 TYP := TP;
  1256.                 IREF := RF;
  1257.                 ADR := SZ
  1258.               END (*WITH*);
  1259.             TESTSEMICOLON;
  1260.           END (*WHILE*)
  1261.       END (*TYPEDECLARATION*);
  1262.  
  1263.  
  1264.     PROCEDURE VARIABLEDECLARATION;
  1265.  
  1266.       VAR
  1267.         T0, T1, RF, SZ: INTEGER;
  1268.         TP: TYPES;
  1269.  
  1270.       BEGIN
  1271.         INSYMBOL;
  1272.         WHILE SY = IDENT DO
  1273.           BEGIN
  1274.             T0 := T;
  1275.             ENTERVARIABLE;
  1276.             WHILE SY = COMMA DO
  1277.               BEGIN
  1278.                 INSYMBOL;
  1279.                 ENTERVARIABLE;
  1280.               END (*WHILE*);
  1281.             IF SY = COLON
  1282.             THEN
  1283.               INSYMBOL
  1284.             ELSE
  1285.               ERROR(5);
  1286.             T1 := T;
  1287.             TYP([SEMICOLON, COMMA, IDENT] + FSYS, TP, RF, SZ);
  1288.             WHILE T0 < T1 DO
  1289.               BEGIN
  1290.                 T0 := T0 + 1;
  1291.                 WITH TAB[T0] DO
  1292.                   BEGIN
  1293.                     TYP := TP;
  1294.                     IREF := RF;
  1295.                     LEV := LEVEL;
  1296.                     ADR := DX;
  1297.                     NORMAL := TRUE;
  1298.                     DX := DX + SZ
  1299.                   END (*WITH*)
  1300.               END (*WHILE*);
  1301.             TESTSEMICOLON
  1302.           END (*WHILE*)
  1303.       END (*VARIABLEDECLARATION*);
  1304.  
  1305.  
  1306.     PROCEDURE PROCDECLARATION;
  1307.  
  1308.       VAR
  1309.         ISFUN: BOOLEAN;
  1310.  
  1311.       BEGIN
  1312.         ISFUN := SY = FUNCTIONSY;
  1313.         INSYMBOL;
  1314.         IF SY <> IDENT THEN
  1315.           BEGIN
  1316.             ERROR(2);
  1317.             ID := '          ';
  1318.           END (*IF*);
  1319.         IF ISFUN
  1320.         THEN
  1321.           ENTER(ID, FUNKTION)
  1322.         ELSE
  1323.           ENTER(ID, PROZEDURE);
  1324.         TAB[T].NORMAL := TRUE;
  1325.         INSYMBOL;
  1326.         BLOCK([SEMICOLON] + FSYS, ISFUN, LEVEL + 1);
  1327.         IF SY = SEMICOLON
  1328.         THEN
  1329.           INSYMBOL
  1330.         ELSE
  1331.           ERROR(14);
  1332.         EMIT(32 + ORD(ISFUN)) (*EXIT*)
  1333.       END (*PROCDECLARATION*);
  1334.  
  1335.  
  1336.     PROCEDURE STATEMENT(FSYS: SYMSET);
  1337.  
  1338.       VAR
  1339.         I: INTEGER;
  1340.         X: ITEM;
  1341.  
  1342.  
  1343.       PROCEDURE EXPRESSION(FSYS: SYMSET; VAR X: ITEM);
  1344.         FORWARD;
  1345.  
  1346.  
  1347.       PROCEDURE SELECTOR(FSYS: SYMSET; VAR V: ITEM);
  1348.  
  1349.         VAR
  1350.           S: ITEM;
  1351.           A, J: INTEGER;
  1352.  
  1353.         BEGIN (* SY IN [LPARENT,LBRACK,PERIOD] *)
  1354.           REPEAT
  1355.             IF SY = PERIOD
  1356.             THEN
  1357.               BEGIN (* FIELD SELECTOR *)
  1358.                 INSYMBOL;
  1359.                 IF SY <> IDENT
  1360.                 THEN
  1361.                   ERROR(2)
  1362.                 ELSE
  1363.                   BEGIN
  1364.                     IF V.TYP <> RECORDS
  1365.                     THEN
  1366.                       ERROR(31)
  1367.                     ELSE
  1368.                       BEGIN (* SEARCH FIELD IDENTIFIER *)
  1369.                         J := BTAB[V.IREF].LAST;
  1370.                         TAB[0].NAME := ID;
  1371.                         WHILE TAB[J].NAME <> ID DO
  1372.                           J := TAB[J].LINK;
  1373.                         IF J = 0 THEN
  1374.                           ERROR(0);
  1375.                         V.TYP := TAB[J].TYP;
  1376.                         V.IREF := TAB[J].IREF;
  1377.                         A := TAB[J].ADR;
  1378.                         IF A <> 0 THEN
  1379.                           EMIT1(9, A)
  1380.                       END (*ELSE*);
  1381.                     INSYMBOL
  1382.                   END (*ELSE*)
  1383.               END (*IF*)
  1384.             ELSE
  1385.               BEGIN (* ARRAY SELECTOR *)
  1386.                 IF SY <> LBRACK THEN
  1387.                   ERROR(11);
  1388.                 REPEAT
  1389.                   INSYMBOL;
  1390.                   EXPRESSION(FSYS + [COMMA, RBRACK], X);
  1391.                   IF V.TYP <> ARRAYS
  1392.                   THEN
  1393.                     ERROR(28)
  1394.                   ELSE
  1395.                     BEGIN
  1396.                       A := V.IREF;
  1397.                       IF ATAB[A].INXTYP <> X.TYP
  1398.                       THEN
  1399.                         ERROR(26)
  1400.                       ELSE
  1401.                         IF ATAB[A].ELSIZE = 1
  1402.                         THEN
  1403.                           EMIT1(20, A)
  1404.                         ELSE
  1405.                           EMIT1(21, A);
  1406.                       V.TYP := ATAB[A].ELTYP;
  1407.                       V.IREF := ATAB[A].ELIREF
  1408.                     END (*ELSE*)
  1409.                 UNTIL SY <> COMMA;
  1410.                 IF SY = RBRACK
  1411.                 THEN
  1412.                   INSYMBOL
  1413.                 ELSE
  1414.                   BEGIN
  1415.                     ERROR(12);
  1416.                     IF SY = RPARENT THEN
  1417.                       INSYMBOL
  1418.                   END (*ELSE*)
  1419.               END (*ELSE*)
  1420.           UNTIL NOT (SY IN [LBRACK, LPARENT, PERIOD]);
  1421.           TEST(FSYS, [], 6)
  1422.         END (*SELECTOR*);
  1423.  
  1424.  
  1425.       PROCEDURE CALL(FSYS: SYMSET; I: INTEGER);
  1426.  
  1427.         VAR
  1428.           X: ITEM;
  1429.           LASTP, CP, K: INTEGER;
  1430.  
  1431.         BEGIN
  1432.           EMIT1(18, I) (* MARK STACK *);
  1433.           LASTP := BTAB[TAB[I].IREF].LASTPAR;
  1434.           CP := I;
  1435.           IF SY = LPARENT
  1436.           THEN
  1437.             BEGIN (* ACTUAL PARAMETER LIST *)
  1438.               REPEAT
  1439.                 INSYMBOL;
  1440.                 IF CP >= LASTP
  1441.                 THEN
  1442.                   ERROR(39)
  1443.                 ELSE
  1444.                   BEGIN
  1445.                     CP := CP + 1;
  1446.                     IF TAB[CP].NORMAL
  1447.                     THEN
  1448.                       BEGIN (* VALUE PARAMETER *)
  1449.                         EXPRESSION(FSYS + [COMMA, COLON, RPARENT], X);
  1450.                         IF X.TYP = TAB[CP].TYP
  1451.                         THEN
  1452.                           BEGIN
  1453.                             IF X.IREF <> TAB[CP].IREF
  1454.                             THEN
  1455.                               ERROR(36)
  1456.                             ELSE
  1457.                               IF X.TYP = ARRAYS
  1458.                               THEN
  1459.                                 EMIT1(22, ATAB[X.IREF].SIZE)
  1460.                               ELSE
  1461.                                 IF X.TYP = RECORDS THEN
  1462.                                   EMIT1(22, BTAB[X.IREF].VSIZE)
  1463.                           END (*IF*)
  1464.                         ELSE
  1465.                           IF (X.TYP = INTS) AND (TAB[CP].TYP = REALS)
  1466.                           THEN
  1467.                             EMIT1(26, 0)
  1468.                           ELSE
  1469.                             IF X.TYP <> NOTYP THEN
  1470.                               ERROR(36);
  1471.                       END (*IF*)
  1472.                     ELSE
  1473.                       BEGIN (* VARAIABLE PARAMETER *)
  1474.                         IF SY <> IDENT
  1475.                         THEN
  1476.                           ERROR(2)
  1477.                         ELSE
  1478.                           BEGIN
  1479.                             K := LOC(ID);
  1480.                             INSYMBOL;
  1481.                             IF K <> 0
  1482.                             THEN
  1483.                               BEGIN
  1484.                                 IF TAB[K].OBJ <> VARIABLE THEN
  1485.                                   ERROR(37);
  1486.                                 X.TYP := TAB[K].TYP;
  1487.                                 X.IREF := TAB[K].IREF;
  1488.                                 IF TAB[K].NORMAL
  1489.                                 THEN
  1490.                                   EMIT2(0, TAB[K].LEV, TAB[K].ADR)
  1491.                                 ELSE
  1492.                                   EMIT2(1, TAB[K].LEV, TAB[K].ADR);
  1493.                                 IF SY IN [LBRACK, LPARENT, PERIOD] THEN
  1494.                                   SELECTOR(FSYS + [COMMA, COLON, RPARENT], X);
  1495.                                 IF (X.TYP <> TAB[CP].TYP) OR (X.IREF <> TAB[CP   .).
  1496.                                   IREF)
  1497.                                 THEN
  1498.                                   ERROR(36)
  1499.                               END (*IF*)
  1500.                           END (*ELSE*)
  1501.                       END (*ELSE*)
  1502.                   END (*ELSE*);
  1503.                 TEST([COMMA, RPARENT], FSYS, 6)
  1504.               UNTIL SY <> COMMA;
  1505.               IF SY = RPARENT
  1506.               THEN
  1507.                 INSYMBOL
  1508.               ELSE
  1509.                 ERROR(4)
  1510.             END (*IF*);
  1511.           IF CP < LASTP THEN
  1512.             ERROR(39);
  1513. (* TOO FEW ACTUAL PARAMETERS *)
  1514.           EMIT1(19, BTAB[TAB[I].IREF].PSIZE - 1);
  1515.           IF TAB[I].LEV < LEVEL THEN
  1516.             EMIT2(3, TAB[I].LEV, LEVEL)
  1517.         END (*CALL*);
  1518.  
  1519.  
  1520.       FUNCTION RESULTTYPE(A, B: TYPES): TYPES;
  1521.  
  1522.         BEGIN
  1523.           IF (A > REALS) OR (B > REALS)
  1524.           THEN
  1525.             BEGIN
  1526.               ERROR(33);
  1527.               RESULTTYPE := NOTYP
  1528.             END (*IF*)
  1529.           ELSE
  1530.             IF (A = NOTYP) OR (B = NOTYP)
  1531.             THEN
  1532.               RESULTTYPE := NOTYP
  1533.             ELSE
  1534.               IF A = INTS
  1535.               THEN
  1536.                 IF B = INTS
  1537.                 THEN
  1538.                   RESULTTYPE := INTS
  1539.                 ELSE
  1540.                   BEGIN
  1541.                     RESULTTYPE := REALS;
  1542.                     EMIT1(26, 1)
  1543.                   END (*ELSE*)
  1544.               ELSE
  1545.                 BEGIN
  1546.                   RESULTTYPE := REALS;
  1547.                   IF B = INTS THEN
  1548.                     EMIT1(26, 0)
  1549.                 END (*ELSE*)
  1550.         END (*RESULTTYPE*);
  1551.  
  1552.  
  1553.       PROCEDURE EXPRESSION;
  1554.  
  1555.         VAR
  1556.           Y: ITEM;
  1557.           OP: SYMBOL;
  1558.  
  1559.  
  1560.         PROCEDURE SIMPLEEXPRESSION(FSYS: SYMSET; VAR X: ITEM);
  1561.  
  1562.           VAR
  1563.             Y: ITEM;
  1564.             OP: SYMBOL;
  1565.  
  1566.  
  1567.           PROCEDURE TERM(FSYS: SYMSET; VAR X: ITEM);
  1568.  
  1569.             VAR
  1570.               Y: ITEM;
  1571.               OP: SYMBOL;
  1572.               TS: TYPSET;
  1573.  
  1574.  
  1575.             PROCEDURE FACTOR(FSYS: SYMSET; VAR X: ITEM);
  1576.  
  1577.               VAR
  1578.                 I, F: INTEGER;
  1579.  
  1580.  
  1581.               PROCEDURE STANDFCT(N: INTEGER);
  1582.  
  1583.                 VAR
  1584.                   TS: TYPSET;
  1585.  
  1586.                 BEGIN (* STANDARD FUNCTION NUMBER N *)
  1587.                   IF SY = LPARENT
  1588.                   THEN
  1589.                     INSYMBOL
  1590.                   ELSE
  1591.                     ERROR(9);
  1592.                   IF N < 17
  1593.                   THEN
  1594.                     BEGIN
  1595.                       EXPRESSION(FSYS + [RPARENT], X);
  1596.                       CASE N OF
  1597.                         0, (* ABS *) 2: (* SQR *)
  1598.                           BEGIN
  1599.                             TS := [INTS, REALS];
  1600.                             TAB[I].TYP := X.TYP;
  1601.                             IF X.TYP = REALS THEN
  1602.                               N := N + 1
  1603.                           END (*0*);
  1604.                         4, (* ODD *) 5: (* CHR *)
  1605.                           TS := [INTS];
  1606.                         6: (* ORD *)
  1607.                           TS := [INTS, BOOLS, CHARS];
  1608.                         7, (* SUCC *) 8: (* PRED *)
  1609.                           TS := [CHARS];
  1610.                         9, (* ROUND *) 10, (* TRUNC *) 11, (* SIN   *) 12, (* CO
  1611.                         S   *) 13, 14, 15, 16:
  1612.                           BEGIN
  1613.                             TS := [INTS, REALS];
  1614.                             IF X.TYP = INTS THEN
  1615.                               EMIT1(26, 0)
  1616.                           END (*9*)
  1617.                       END (*CASE*);
  1618.                       IF X.TYP IN TS
  1619.                       THEN
  1620.                         EMIT1(8, N)
  1621.                       ELSE
  1622.                         IF X.TYP <> NOTYP THEN
  1623.                           ERROR(48);
  1624.                     END (*IF*)
  1625.                   ELSE
  1626.                     BEGIN (* N IN [17,18] *)
  1627.                       IF SY <> IDENT
  1628.                       THEN
  1629.                         ERROR(2)
  1630.                       ELSE
  1631.                         IF ID <> 'INPUT     '
  1632.                         THEN
  1633.                           ERROR(0)
  1634.                         ELSE
  1635.                           INSYMBOL;
  1636.                       EMIT1(8, N)
  1637.                     END (*ELSE*);
  1638.                   X.TYP := TAB[I].TYP;
  1639.                   IF SY = RPARENT
  1640.                   THEN
  1641.                     INSYMBOL
  1642.                   ELSE
  1643.                     ERROR(4)
  1644.                 END (*STANDFCT*);
  1645.  
  1646.  
  1647.               BEGIN (* FACTOR *)
  1648.                 X.TYP := NOTYP;
  1649.                 X.IREF := 0;
  1650.                 TEST(FACBEGSYS, FSYS, 58);
  1651.                 WHILE SY IN FACBEGSYS DO
  1652.                   BEGIN
  1653.                     IF SY = IDENT
  1654.                     THEN
  1655.                       BEGIN
  1656.                         I := LOC(ID);
  1657.                         INSYMBOL;
  1658.                         WITH TAB[I] DO
  1659.                           CASE OBJ OF
  1660.                             KONSTANT:
  1661.                               BEGIN
  1662.                                 X.TYP := TYP;
  1663.                                 X.IREF := 0;
  1664.                                 IF X.TYP = REALS THEN
  1665.                                   IF X.TYP = REALS
  1666.                                   THEN
  1667.                                     EMIT1(25, ADR)
  1668.                                   ELSE
  1669.                                     EMIT1(24, ADR)
  1670.                               END (*KONSTANT*);
  1671.                             VARIABLE:
  1672.                               BEGIN
  1673.                                 X.TYP := TYP;
  1674.                                 X.IREF := IREF;
  1675.                                 IF SY IN [LBRACK, LPARENT, PERIOD]
  1676.                                 THEN
  1677.                                   BEGIN
  1678.                                     IF NORMAL
  1679.                                     THEN
  1680.                                       F := 0
  1681.                                     ELSE
  1682.                                       F := 1;
  1683.                                     EMIT2(F, LEV, ADR);
  1684.                                     SELECTOR(FSYS, X);
  1685.                                     IF X.TYP IN STANTYPS THEN
  1686.                                       EMIT(34)
  1687.                                   END (*IF*)
  1688.                                 ELSE
  1689.                                   BEGIN
  1690.                                     IF X.TYP IN STANTYPS
  1691.                                     THEN
  1692.                                       IF NORMAL
  1693.                                       THEN
  1694.                                         F := 1
  1695.                                       ELSE
  1696.                                         F := 2
  1697.                                     ELSE
  1698.                                       IF NORMAL
  1699.                                       THEN
  1700.                                         F := 0
  1701.                                       ELSE
  1702.                                         F := 1;
  1703.                                     EMIT2(F, LEV, ADR)
  1704.                                   END (*ELSE*)
  1705.                               END (*VARIABLE*);
  1706.                             TYPE1, PROZEDURE:
  1707.                               ERROR(44);
  1708.                             FUNKTION:
  1709.                               BEGIN
  1710.                                 X.TYP := TYP;
  1711.                                 IF LEV <> 0
  1712.                                 THEN
  1713.                                   CALL(FSYS, I)
  1714.                                 ELSE
  1715.                                   STANDFCT(ADR)
  1716.                               END (*FUNKTION*)
  1717.                           END (*CASE*)
  1718.                       END (*IF*)
  1719.                     ELSE
  1720.                       IF SY IN [CHARCON, INTCON, REALCON]
  1721.                       THEN
  1722.                         BEGIN
  1723.                           IF SY = REALCON
  1724.                           THEN
  1725.                             BEGIN
  1726.                               X.TYP := REALS;
  1727.                               ENTERREAL(RNUM);
  1728.                               EMIT1(25, C1)
  1729.                             END (*IF*)
  1730.                           ELSE
  1731.                             BEGIN
  1732.                               IF SY = CHARCON
  1733.                               THEN
  1734.                                 X.TYP := CHARS
  1735.                               ELSE
  1736.                                 X.TYP := INTS;
  1737.                               EMIT1(24, INUM)
  1738.                             END (*ELSE*);
  1739.                           X.IREF := 0;
  1740.                           INSYMBOL
  1741.                         END (*IF*)
  1742.                       ELSE
  1743.                         IF SY = LPARENT
  1744.                         THEN
  1745.                           BEGIN
  1746.                             INSYMBOL;
  1747.                             EXPRESSION(FSYS + [RPARENT], X);
  1748.                             IF SY = RPARENT
  1749.                             THEN
  1750.                               INSYMBOL
  1751.                             ELSE
  1752.                               ERROR(4)
  1753.                           END (*IF*)
  1754.                         ELSE
  1755.                           IF SY = NOTSY THEN
  1756.                             BEGIN
  1757.                               INSYMBOL;
  1758.                               FACTOR(FSYS, X);
  1759.                               IF X.TYP = BOOLS
  1760.                               THEN
  1761.                                 EMIT(35)
  1762.                               ELSE
  1763.                                 IF X.TYP <> NOTYP THEN
  1764.                                   ERROR(32)
  1765.                             END (*IF*);
  1766.                     TEST(FSYS, FACBEGSYS, 6)
  1767.                   END (*WHILE*)
  1768.               END (*FACTOR*);
  1769.  
  1770.  
  1771.             BEGIN (*TERM*)
  1772.               FACTOR(FSYS + [TIMES, RDIV, IDIV, IMOD, ANDSY], X);
  1773.               WHILE SY IN [TIMES, RDIV, IDIV, IMOD, ANDSY] DO
  1774.                 BEGIN
  1775.                   OP := SY;
  1776.                   INSYMBOL;
  1777.                   FACTOR(FSYS + [TIMES, RDIV, IDIV, IMOD, ANDSY], Y);
  1778.                   IF OP = TIMES
  1779.                   THEN
  1780.                     BEGIN
  1781.                       X.TYP := RESULTTYPE(X.TYP, Y.TYP);
  1782.                       CASE X.TYP OF
  1783.                         NOTYP:;
  1784.                         INTS:
  1785.                           EMIT(57);
  1786.                         REALS:
  1787.                           EMIT(60)
  1788.                       END (*CASE*)
  1789.                     END (*IF*)
  1790.                   ELSE
  1791.                     IF OP = RDIV
  1792.                     THEN
  1793.                       BEGIN
  1794.                         IF X.TYP = INTS THEN
  1795.                           BEGIN
  1796.                             EMIT1(26, 1);
  1797.                             X.TYP := REALS
  1798.                           END (*IF*);
  1799.                         IF Y.TYP = INTS THEN
  1800.                           BEGIN
  1801.                             EMIT1(26, 0);
  1802.                             Y.TYP := REALS
  1803.                           END (*IF*);
  1804.                         IF (X.TYP = REALS) AND (Y.TYP = REALS)
  1805.                         THEN
  1806.                           EMIT(61)
  1807.                         ELSE
  1808.                           BEGIN
  1809.                             IF (X.TYP <> NOTYP) AND (Y.TYP <> NOTYP) THEN
  1810.                               ERROR(33);
  1811.                             X.TYP := NOTYP
  1812.                           END (*ELSE*)
  1813.                       END (*IF*)
  1814.                     ELSE
  1815.                       IF OP = ANDSY
  1816.                       THEN
  1817.                         BEGIN
  1818.                           IF (X.TYP = BOOLS) AND (Y.TYP = BOOLS)
  1819.                           THEN
  1820.                             EMIT(56)
  1821.                           ELSE
  1822.                             BEGIN
  1823.                               IF (X.TYP <> NOTYP) AND (Y.TYP <> NOTYP) THEN
  1824.                                 ERROR(32);
  1825.                               X.TYP := NOTYP
  1826.                             END (*ELSE*)
  1827.                         END (*IF*)
  1828.                       ELSE
  1829.                         BEGIN (* OP IN IDIV,IMOD *)
  1830.                           IF (X.TYP = INTS) AND (Y.TYP = INTS)
  1831.                           THEN
  1832.                             IF OP = IDIV
  1833.                             THEN
  1834.                               EMIT(58)
  1835.                             ELSE
  1836.                               EMIT(59)
  1837.                           ELSE
  1838.                             BEGIN
  1839.                               IF (X.TYP <> NOTYP) AND (Y.TYP <> NOTYP) THEN
  1840.                                 ERROR(34);
  1841.                               X.TYP := NOTYP
  1842.                             END (*ELSE*)
  1843.                         END (*ELSE*)
  1844.                 END (*WHILE*)
  1845.             END (*TERM*);
  1846.  
  1847.  
  1848.           BEGIN (* SIMPLEEXPRESSION *)
  1849.             IF SY IN [PLUS, MINUS]
  1850.             THEN
  1851.               BEGIN
  1852.                 OP := SY;
  1853.                 INSYMBOL;
  1854.                 TERM(FSYS + [PLUS, MINUS], X);
  1855.                 IF X.TYP > REALS
  1856.                 THEN
  1857.                   ERROR(33)
  1858.                 ELSE
  1859.                   IF OP = MINUS THEN
  1860.                     EMIT(36)
  1861.               END (*IF*)
  1862.             ELSE
  1863.               TERM(FSYS + [PLUS, MINUS, ORSY], X);
  1864.             WHILE SY IN [PLUS, MINUS, ORSY] DO
  1865.               BEGIN
  1866.                 OP := SY;
  1867.                 INSYMBOL;
  1868.                 TERM(FSYS + [PLUS, MINUS, ORSY], Y);
  1869.                 IF OP = ORSY
  1870.                 THEN
  1871.                   BEGIN
  1872.                     IF (X.TYP = BOOLS) AND (Y.TYP = BOOLS)
  1873.                     THEN
  1874.                       EMIT(51)
  1875.                     ELSE
  1876.                       BEGIN
  1877.                         IF (X.TYP <> NOTYP) AND (Y.TYP <> NOTYP) THEN
  1878.                           ERROR(32);
  1879.                         X.TYP := NOTYP
  1880.                       END (*ELSE*)
  1881.                   END (*IF*)
  1882.                 ELSE
  1883.                   BEGIN
  1884.                     X.TYP := RESULTTYPE(X.TYP, Y.TYP);
  1885.                     CASE X.TYP OF
  1886.                       NOTYP:;
  1887.                       INTS:
  1888.                         IF OP = PLUS
  1889.                         THEN
  1890.                           EMIT(52)
  1891.                         ELSE
  1892.                           EMIT(53);
  1893.                       REALS:
  1894.                         IF OP = PLUS
  1895.                         THEN
  1896.                           EMIT(54)
  1897.                         ELSE
  1898.                           EMIT(55)
  1899.                     END (*CASE*)
  1900.                   END (*ELSE*)
  1901.               END (*WHILE*)
  1902.           END (*SIMPLEEXPRESSION*);
  1903.  
  1904.  
  1905.         BEGIN (* EXPRESSION *)
  1906.           SIMPLEEXPRESSION(FSYS + [EQL, NEQ, LSS, LEQ, GTR, GEQ], X);
  1907.           IF SY IN [EQL, NEQ, LSS, LEQ, GTR, GEQ]
  1908.           THEN
  1909.             BEGIN
  1910.               OP := SY;
  1911.               INSYMBOL;
  1912.               SIMPLEEXPRESSION(FSYS, Y);
  1913.               IF (X.TYP IN [NOTYP, INTS, BOOLS, CHARS]) AND (X.TYP = Y.TYP)
  1914.               THEN
  1915.                 CASE OP OF
  1916.                   EQL:
  1917.                     EMIT(45);
  1918.                   NEQ:
  1919.                     EMIT(46);
  1920.                   LSS:
  1921.                     EMIT(47);
  1922.                   LEQ:
  1923.                     EMIT(48);
  1924.                   GTR:
  1925.                     EMIT(49);
  1926.                   GEQ:
  1927.                     EMIT(50)
  1928.                 END (*CASE*)
  1929.               ELSE
  1930.                 BEGIN
  1931.                   IF X.TYP = INTS
  1932.                   THEN
  1933.                     BEGIN
  1934.                       X.TYP := REALS;
  1935.                       EMIT1(26, 1)
  1936.                     END (*IF*)
  1937.                   ELSE
  1938.                     IF Y.TYP = INTS THEN
  1939.                       BEGIN
  1940.                         Y.TYP := REALS;
  1941.                         EMIT1(26, 0)
  1942.                       END (*IF*);
  1943.                   IF (X.TYP = REALS) AND (Y.TYP = REALS)
  1944.                   THEN
  1945.                     CASE OP OF
  1946.                       EQL:
  1947.                         EMIT(39);
  1948.                       NEQ:
  1949.                         EMIT(40);
  1950.                       LSS:
  1951.                         EMIT(41);
  1952.                       LEQ:
  1953.                         EMIT(42);
  1954.                       GTR:
  1955.                         EMIT(43);
  1956.                       GEQ:
  1957.                         EMIT(44)
  1958.                     END (*CASE*)
  1959.                   ELSE
  1960.                     ERROR(35)
  1961.                 END (*ELSE*);
  1962.               X.TYP := BOOLS
  1963.             END (*IF*)
  1964.         END (*EXPRESSION*);
  1965.  
  1966.  
  1967.       PROCEDURE ASSIGNMENT(LV, AD: INTEGER);
  1968.  
  1969.         VAR
  1970.           X, Y: ITEM;
  1971.           F: INTEGER;
  1972. (* TAB[I].OBJ IN [VARIABLE,PROZEDURE]*)
  1973.  
  1974.         BEGIN
  1975.           X.TYP := TAB[I].TYP;
  1976.           X.IREF := TAB[I].IREF;
  1977.           IF TAB[I].NORMAL
  1978.           THEN
  1979.             F := 0
  1980.           ELSE
  1981.             F := 1;
  1982.           EMIT2(F, LV, AD);
  1983.           IF SY IN [LBRACK, LPARENT, PERIOD] THEN
  1984.             SELECTOR([BECOMES, EQL] + FSYS, X);
  1985.           IF SY = BECOMES
  1986.           THEN
  1987.             INSYMBOL
  1988.           ELSE
  1989.             BEGIN
  1990.               ERROR(51);
  1991.               IF SY = EQL THEN
  1992.                 INSYMBOL
  1993.             END (*ELSE*);
  1994.           EXPRESSION(FSYS, Y);
  1995.           IF X.TYP = Y.TYP
  1996.           THEN
  1997.             IF X.TYP IN STANTYPS
  1998.             THEN
  1999.               EMIT(38)
  2000.             ELSE
  2001.               IF X.IREF <> Y.IREF
  2002.               THEN
  2003.                 ERROR(46)
  2004.               ELSE
  2005.                 IF X.TYP = ARRAYS
  2006.                 THEN
  2007.                   EMIT1(23, ATAB[X.IREF].SIZE)
  2008.                 ELSE
  2009.                   EMIT1(23, BTAB[X.IREF].VSIZE)
  2010.           ELSE
  2011.             IF (X.TYP = REALS) AND (Y.TYP = INTS)
  2012.             THEN
  2013.               BEGIN
  2014.                 EMIT1(26, 0);
  2015.                 EMIT(38)
  2016.               END (*IF*)
  2017.             ELSE
  2018.               IF (X.TYP <> NOTYP) AND (Y.TYP <> NOTYP) THEN
  2019.                 ERROR(46)
  2020.         END (*ASSIGNMENT*);
  2021.  
  2022.  
  2023.       PROCEDURE COMPOUNDSTATEMENT;
  2024.  
  2025.         BEGIN
  2026.           INSYMBOL;
  2027.           WHILE SY IN [SEMICOLON] + STATBEGSYS DO
  2028.             BEGIN
  2029.               IF SY = SEMICOLON
  2030.               THEN
  2031.                 INSYMBOL
  2032.               ELSE
  2033.                 ERROR(14);
  2034.               STATEMENT([SEMICOLON, ENDSY] + FSYS)
  2035.             END (*WHILE*);
  2036.           IF SY = ENDSY
  2037.           THEN
  2038.             INSYMBOL
  2039.           ELSE
  2040.             ERROR(57)
  2041.         END (*COMPOUNDSTATEMENT*);
  2042.  
  2043.  
  2044.       PROCEDURE IFSTATEMENT;
  2045.  
  2046.         VAR
  2047.           X: ITEM;
  2048.           LC1, LC2: INTEGER;
  2049.  
  2050.         BEGIN
  2051.           INSYMBOL;
  2052.           EXPRESSION(FSYS + [THENSY, DOSY], X);
  2053.           IF NOT (X.TYP IN [BOOLS, NOTYP]) THEN
  2054.             ERROR(17);
  2055.           LC1 := LC;
  2056.           EMIT(11);
  2057. (* JMPC *)
  2058.           IF SY = THENSY
  2059.           THEN
  2060.             INSYMBOL
  2061.           ELSE
  2062.             BEGIN
  2063.               ERROR(52);
  2064.               IF SY = DOSY THEN
  2065.                 INSYMBOL
  2066.             END (*ELSE*);
  2067.           STATEMENT(FSYS + [ELSESY]);
  2068.           IF SY = ELSESY
  2069.           THEN
  2070.             BEGIN
  2071.               INSYMBOL;
  2072.               LC2 := LC;
  2073.               EMIT(10);
  2074.               CODE[LC1].Y := LC;
  2075.               STATEMENT(FSYS);
  2076.               CODE[LC2].Y := LC
  2077.             END (*IF*)
  2078.           ELSE
  2079.             CODE[LC1].Y := LC
  2080.         END (*IFSTATEMENT*);
  2081.  
  2082.  
  2083.       PROCEDURE CASESTATEMENT;
  2084.  
  2085.         VAR
  2086.           X: ITEM;
  2087.           I, J, K, LC1: INTEGER;
  2088.           CASETAB: ARRAY [1.. CSMAX] OF PACKED RECORD
  2089.                                                         VAL,
  2090.                                                          LC: INDEX
  2091.                                                END;
  2092.           EXITTAB: ARRAY [1 .. CSMAX] OF INTEGER;
  2093.  
  2094.  
  2095.         PROCEDURE CASELABEL;
  2096.  
  2097.           VAR
  2098.             LAB: CONREC;
  2099.             K: INTEGER;
  2100.  
  2101.           BEGIN
  2102.             CONSTANT(FSYS + [COMMA, COLON], LAB);
  2103.             IF LAB.TP <> X.TYP
  2104.             THEN
  2105.               ERROR(47)
  2106.             ELSE
  2107.               IF I = CSMAX
  2108.               THEN
  2109.                 FATAL(6)
  2110.               ELSE
  2111.                 BEGIN
  2112.                   I := I + 1;
  2113.                   K := 0;
  2114.                   CASETAB[I].VAL := LAB.I;
  2115.                   CASETAB[I].LC := LC;
  2116.                   REPEAT
  2117.                     K := K + 1;
  2118.                   UNTIL CASETAB[K].VAL = LAB.I;
  2119.                   IF K < I THEN
  2120.                     ERROR(1);
  2121. (* MULTIPLE DEF *)
  2122.                 END (*ELSE*)
  2123.           END (*CASELABEL*);
  2124.  
  2125.  
  2126.         PROCEDURE ONECASE;
  2127.  
  2128.           BEGIN
  2129.             IF SY IN CONSTBEGSYS
  2130.             THEN
  2131.               BEGIN
  2132.                 CASELABEL;
  2133.                 WHILE SY = COMMA DO
  2134.                   BEGIN
  2135.                     INSYMBOL;
  2136.                     CASELABEL
  2137.                   END (*WHILE*);
  2138.                 IF SY = COLON
  2139.                 THEN
  2140.                   INSYMBOL
  2141.                 ELSE
  2142.                   ERROR(5);
  2143.                 STATEMENT([SEMICOLON, ENDSY] + FSYS);
  2144.                 J := J + 1;
  2145.                 EXITTAB[J] := LC;
  2146.                 EMIT(10)
  2147.               END (*IF*)
  2148.           END (*ONECASE*);
  2149.  
  2150.  
  2151.         BEGIN (*CASESTATEMENT*)
  2152.           INSYMBOL;
  2153.           I := 0;
  2154.           J := 0;
  2155.           EXPRESSION(FSYS + [OFSY, COMMA, COLON], X);
  2156.           IF NOT (X.TYP IN [INTS, BOOLS, CHARS, NOTYP]) THEN
  2157.             ERROR(23);
  2158.           LC1 := LC;
  2159.           EMIT(12);
  2160. (* JMPX *)
  2161.           IF SY = OFSY
  2162.           THEN
  2163.             INSYMBOL
  2164.           ELSE
  2165.             ERROR(8);
  2166.           ONECASE;
  2167.           WHILE SY = SEMICOLON DO
  2168.             BEGIN
  2169.               INSYMBOL;
  2170.               ONECASE
  2171.             END (*WHILE*);
  2172.           CODE[LC1].Y := LC;
  2173.           FOR K := 1 TO I DO
  2174.             BEGIN
  2175.               EMIT1(13, CASETAB[K].VAL);
  2176.               EMIT1(13, CASETAB[K].LC)
  2177.             END (*FOR*);
  2178.           EMIT1(10, 0);
  2179.           FOR K := 1 TO J DO
  2180.             CODE[EXITTAB[K]].Y := LC;
  2181.           IF SY = ENDSY
  2182.           THEN
  2183.             INSYMBOL
  2184.           ELSE
  2185.             ERROR(57)
  2186.         END (*CASESTATEMENT*);
  2187.  
  2188.  
  2189.       PROCEDURE REPEATSTATEMENT;
  2190.  
  2191.         VAR
  2192.           X: ITEM;
  2193.           LC1: INTEGER;
  2194.  
  2195.         BEGIN
  2196.           LC1 := LC;
  2197.           INSYMBOL;
  2198.           STATEMENT([SEMICOLON, UNTILSY] + FSYS);
  2199.           WHILE SY IN [SEMICOLON] + STATBEGSYS DO
  2200.             BEGIN
  2201.               IF SY = SEMICOLON
  2202.               THEN
  2203.                 INSYMBOL
  2204.               ELSE
  2205.                 ERROR(14);
  2206.               STATEMENT([SEMICOLON, UNTILSY] + FSYS)
  2207.             END (*WHILE*);
  2208.           IF SY = UNTILSY
  2209.           THEN
  2210.             BEGIN
  2211.               INSYMBOL;
  2212.               EXPRESSION(FSYS, X);
  2213.               IF NOT (X.TYP IN [BOOLS, NOTYP]) THEN
  2214.                 ERROR(17);
  2215.               EMIT1(11, LC1)
  2216.             END (*IF*)
  2217.           ELSE
  2218.             ERROR(53)
  2219.         END (*REPEATSTATEMENT*);
  2220.  
  2221.  
  2222.       PROCEDURE WHILESTATEMENT;
  2223.  
  2224.         VAR
  2225.           X: ITEM;
  2226.           LC1, LC2: INTEGER;
  2227.  
  2228.         BEGIN
  2229.           INSYMBOL;
  2230.           LC1 := LC;
  2231.           EXPRESSION(FSYS + [DOSY], X);
  2232.           IF NOT (X.TYP IN [BOOLS, NOTYP]) THEN
  2233.             ERROR(17);
  2234.           LC2 := LC;
  2235.           EMIT(11);
  2236.           IF SY = DOSY
  2237.           THEN
  2238.             INSYMBOL
  2239.           ELSE
  2240.             ERROR(54);
  2241.           STATEMENT(FSYS);
  2242.           EMIT1(10, LC1);
  2243.           CODE[LC1].Y := LC
  2244.         END (*WHILESTATEMENT*);
  2245.  
  2246.  
  2247.       PROCEDURE FORSTATEMENT;
  2248.  
  2249.         VAR
  2250.           CVT: TYPES;
  2251.           X: ITEM;
  2252.           I, F, LC1, LC2: INTEGER;
  2253.  
  2254.         BEGIN
  2255.           INSYMBOL;
  2256.           IF SY = IDENT
  2257.           THEN
  2258.             BEGIN
  2259.               I := LOC(ID);
  2260.               INSYMBOL;
  2261.               IF I = 0
  2262.               THEN
  2263.                 CVT := INTS
  2264.               ELSE
  2265.                 IF TAB[I].OBJ = VARIABLE
  2266.                 THEN
  2267.                   BEGIN
  2268.                     CVT := TAB[I].TYP;
  2269.                     EMIT2(0, TAB[I].LEV, TAB[I].ADR);
  2270.                     IF NOT (CVT IN [NOTYP, INTS, BOOLS, CHARS]) THEN
  2271.                       ERROR(18)
  2272.                   END (*IF*)
  2273.                 ELSE
  2274.                   BEGIN
  2275.                     ERROR(37);
  2276.                     CVT := INTS
  2277.                   END (*ELSE*)
  2278.             END (*IF*)
  2279.           ELSE
  2280.             SKIP([BECOMES, TOSY, DOWNTOSY, DOSY] + FSYS, 2);
  2281.           IF SY = BECOMES
  2282.           THEN
  2283.             BEGIN
  2284.               INSYMBOL;
  2285.               EXPRESSION([TOSY, DOWNTOSY, DOSY] + FSYS, X);
  2286.               IF X.TYP <> CVT THEN
  2287.                 ERROR(19);
  2288.             END (*IF*)
  2289.           ELSE
  2290.             SKIP([TOSY, DOWNTOSY, DOSY] + FSYS, 51);
  2291.           F := 14;
  2292.           IF SY IN [TOSY, DOWNTOSY]
  2293.           THEN
  2294.             BEGIN
  2295.               IF SY = DOWNTOSY THEN
  2296.                 F := 16;
  2297.               INSYMBOL;
  2298.               EXPRESSION([DOSY] + FSYS, X);
  2299.               IF X.TYP <> CVT THEN
  2300.                 ERROR(19)
  2301.             END (*IF*)
  2302.           ELSE
  2303.             SKIP([DOSY] + FSYS, 55);
  2304.           LC1 := LC;
  2305.           EMIT(F);
  2306.           IF SY = DOSY
  2307.           THEN
  2308.             INSYMBOL
  2309.           ELSE
  2310.             ERROR(54);
  2311.           LC2 := LC;
  2312.           STATEMENT(FSYS);
  2313.           EMIT1(F + 1, LC2);
  2314.           CODE[LC1].Y := LC
  2315.         END (*FORSTATEMENT*);
  2316.  
  2317.  
  2318.       PROCEDURE STANDPROC(N: INTEGER);
  2319.  
  2320.         VAR
  2321.           I, F: INTEGER;
  2322.           X, Y: ITEM;
  2323.  
  2324.         BEGIN
  2325.           CASE N OF
  2326.             1, 2:
  2327.               BEGIN (* READ *)
  2328.                 IF NOT IFLAG THEN
  2329.                   BEGIN
  2330.                     ERROR(20);
  2331.                     IFLAG := TRUE
  2332.                   END (*IF*);
  2333.                 IF SY = LPARENT
  2334.                 THEN
  2335.                   BEGIN
  2336.                     REPEAT
  2337.                       INSYMBOL;
  2338.                       IF SY <> IDENT
  2339.                       THEN
  2340.                         ERROR(2)
  2341.                       ELSE
  2342.                         BEGIN
  2343.                           I := LOC(ID);
  2344.                           INSYMBOL;
  2345.                           IF I <> 0
  2346.                           THEN
  2347.                             IF TAB[I].OBJ <> VARIABLE
  2348.                             THEN
  2349.                               ERROR(37)
  2350.                             ELSE
  2351.                               BEGIN
  2352.                                 X.TYP := TAB[I].TYP;
  2353.                                 X.IREF := TAB[I].IREF;
  2354.                                 IF TAB[I].NORMAL
  2355.                                 THEN
  2356.                                   F := 0
  2357.                                 ELSE
  2358.                                   F := 1;
  2359.                                 EMIT2(F, TAB[I].LEV, TAB[I].ADR);
  2360.                                 IF SY IN [LBRACK, LPARENT, PERIOD] THEN
  2361.                                   SELECTOR(FSYS + [COMMA, RPARENT], X);
  2362.                                 IF X.TYP IN [INTS, REALS, CHARS, NOTYP]
  2363.                                 THEN
  2364.                                   EMIT1(27, ORD(X.TYP))
  2365.                                 ELSE
  2366.                                   ERROR(40)
  2367.                               END (*ELSE*)
  2368.                         END (*ELSE*);
  2369.                       TEST([COMMA, RPARENT], FSYS, 6)
  2370.                     UNTIL SY <> COMMA;
  2371.                     IF SY = RPARENT
  2372.                     THEN
  2373.                       INSYMBOL
  2374.                     ELSE
  2375.                       ERROR(4)
  2376.                   END (*IF*);
  2377.                 IF N = 2 THEN
  2378.                   EMIT(62)
  2379.               END (*1*);
  2380.             3, 4:
  2381.               BEGIN (*WRITE*)
  2382.                 IF SY = LPARENT
  2383.                 THEN
  2384.                   BEGIN
  2385.                     REPEAT
  2386.                       INSYMBOL;
  2387.                       IF SY = STRING
  2388.                       THEN
  2389.                         BEGIN
  2390.                           EMIT1(24, SLENG);
  2391.                           EMIT1(28, INUM);
  2392.                           INSYMBOL
  2393.                         END (*IF*)
  2394.                       ELSE
  2395.                         BEGIN
  2396.                           EXPRESSION(FSYS + [COMMA, COLON, RPARENT], X);
  2397.                           IF NOT (X.TYP IN STANTYPS) THEN
  2398.                             ERROR(41);
  2399.                           IF SY = COLON
  2400.                           THEN
  2401.                             BEGIN
  2402.                               INSYMBOL;
  2403.                               EXPRESSION(FSYS + [COMMA, COLON, RPARENT], Y);
  2404.                               IF Y.TYP <> INTS THEN
  2405.                                 ERROR(43);
  2406.                               IF SY = COLON
  2407.                               THEN
  2408.                                 BEGIN
  2409.                                   IF X.TYP <> REALS THEN
  2410.                                     ERROR(42);
  2411.                                   INSYMBOL;
  2412.                                   EXPRESSION(FSYS + [COMMA, RPARENT], Y);
  2413.                                   IF Y.TYP <> INTS THEN
  2414.                                     ERROR(43);
  2415.                                   EMIT(37)
  2416.                                 END (*IF*)
  2417.                               ELSE
  2418.                                 EMIT1(30, ORD(X.TYP))
  2419.                             END (*IF*)
  2420.                           ELSE
  2421.                             EMIT1(29, ORD(X.TYP))
  2422.                         END (*ELSE*)
  2423.                     UNTIL SY <> COMMA;
  2424.                     IF SY = RPARENT
  2425.                     THEN
  2426.                       INSYMBOL
  2427.                     ELSE
  2428.                       ERROR(4)
  2429.                   END (*IF*);
  2430.                 IF N = 4 THEN
  2431.                   EMIT(63)
  2432.               END (*3*)
  2433.           END (*CASE*)
  2434.         END (*STANDPROC*);
  2435.  
  2436.  
  2437.       BEGIN (* STATEMENT *)
  2438.         IF SY IN STATBEGSYS + [IDENT]
  2439.         THEN
  2440.           CASE SY OF
  2441.             IDENT:
  2442.               BEGIN
  2443.                 I := LOC(ID);
  2444.                 INSYMBOL;
  2445.                 IF I <> 0
  2446.                 THEN
  2447.                   CASE TAB[I].OBJ OF
  2448.                     KONSTANT, TYPE1:
  2449.                       ERROR(45);
  2450.                     VARIABLE:
  2451.                       ASSIGNMENT(TAB[I].LEV, TAB[I].ADR);
  2452.                     PROZEDURE:
  2453.                       IF TAB[I].LEV <> 0
  2454.                       THEN
  2455.                         CALL(FSYS, I)
  2456.                       ELSE
  2457.                         STANDPROC(TAB[I].ADR);
  2458.                     FUNKTION:
  2459.                       IF TAB[I].IREF = DISPLAY[LEVEL]
  2460.                       THEN
  2461.                         ASSIGNMENT(TAB[I].LEV + 1, 0)
  2462.                       ELSE
  2463.                         ERROR(45)
  2464.                   END (*CASE*)
  2465.               END (*IDENT*);
  2466.             BEGINSY:
  2467.               COMPOUNDSTATEMENT;
  2468.             IFSY:
  2469.               IFSTATEMENT;
  2470.             CASESY:
  2471.               CASESTATEMENT;
  2472.             WHILESY:
  2473.               WHILESTATEMENT;
  2474.             REPEATSY:
  2475.               REPEATSTATEMENT;
  2476.             FORSY:
  2477.               FORSTATEMENT
  2478.           END (*CASE*);
  2479.         TEST(FSYS, [], 14)
  2480.       END (*STATEMENT*);
  2481.  
  2482.  
  2483.     BEGIN (*BLOCK*)
  2484.       DX := 5;
  2485.       PRT := T;
  2486.       IF LEVEL > LMAX THEN
  2487.         FATAL(5);
  2488.       TEST([LPARENT, COLON, SEMICOLON], FSYS, 7);
  2489.       ENTERBLOCK;
  2490.       DISPLAY[LEVEL] := B;
  2491.       PRB := B;
  2492.       TAB[PRT].TYP := NOTYP;
  2493.       TAB[PRT].IREF := PRB;
  2494.       IF SY = LPARENT THEN
  2495.         PARAMETERLIST;
  2496.       BTAB[PRB].LASTPAR := T;
  2497.       BTAB[PRB].PSIZE := DX;
  2498.       IF ISFUN
  2499.       THEN
  2500.         IF SY = COLON
  2501.         THEN
  2502.           BEGIN
  2503.             INSYMBOL (* FUNCTION TYPE *);
  2504.             IF SY = IDENT
  2505.             THEN
  2506.               BEGIN
  2507.                 X := LOC(ID);
  2508.                 INSYMBOL;
  2509.                 IF X <> 0 THEN
  2510.                   IF TAB[X].OBJ <> TYPE1
  2511.                   THEN
  2512.                     ERROR(29)
  2513.                   ELSE
  2514.                     IF TAB[X].TYP IN STANTYPS
  2515.                     THEN
  2516.                       TAB[PRT].TYP := TAB[X].TYP
  2517.                     ELSE
  2518.                       ERROR(15)
  2519.               END (*IF*)
  2520.             ELSE
  2521.               SKIP([SEMICOLON] + FSYS, 2)
  2522.           END (*IF*)
  2523.         ELSE
  2524.           ERROR(5);
  2525.       IF SY = SEMICOLON
  2526.       THEN
  2527.         INSYMBOL
  2528.       ELSE
  2529.         ERROR(14);
  2530.       REPEAT
  2531.         IF SY = CONSTSY THEN
  2532.           CONSTANTDECLARATION;
  2533.         IF SY = TYPESY THEN
  2534.           TYPEDECLARATION;
  2535.         IF SY = VARSY THEN
  2536.           VARIABLEDECLARATION;
  2537.         BTAB[PRB].VSIZE := DX;
  2538.         WHILE SY IN [PROCEDURESY, FUNCTIONSY] DO
  2539.           PROCDECLARATION;
  2540.         TEST([BEGINSY], BLOCKBEGSYS + STATBEGSYS, 56)
  2541.       UNTIL SY IN STATBEGSYS;
  2542.       TAB[PRT].ADR := LC;
  2543.       INSYMBOL;
  2544.       STATEMENT([SEMICOLON, ENDSY] + FSYS);
  2545.       WHILE SY IN [SEMICOLON] + STATBEGSYS DO
  2546.         BEGIN
  2547.           IF SY = SEMICOLON
  2548.           THEN
  2549.             INSYMBOL
  2550.           ELSE
  2551.             ERROR(14);
  2552.           STATEMENT([SEMICOLON, ENDSY] + FSYS)
  2553.         END (*WHILE*);
  2554.       IF SY = ENDSY
  2555.       THEN
  2556.         INSYMBOL
  2557.       ELSE
  2558.         ERROR(57);
  2559.       TEST(FSYS + [PERIOD], [], 6)
  2560.     END (*BLOCK*);
  2561.  
  2562.  
  2563.   PROCEDURE INTERPRET;
  2564.  
  2565.     VAR
  2566.       IR: ORDER;
  2567.       PC: INTEGER;
  2568.       PS: (RUN, FIN, CASCHK, DIVCHK, INXCHK, STKCHK, LINCHK, LNGCHK, REDCHK);
  2569.       T: INTEGER;
  2570.       B: INTEGER;
  2571.       LNCNT, OCNT, BLKCNT, CHRCNT, REMOVE: INTEGER;
  2572.       H1, H2, H3, H4: INTEGER;
  2573.       FLD: ARRAY [1..4] OF INTEGER;
  2574.       DISPLAY: ARRAY [1.. LMAX] OF INTEGER;
  2575.       S: ARRAY [1.. STACKSIZE] OF RECORD
  2576.                                     CASE TYPES OF
  2577.                                       INTS: (         I: INTEGER);
  2578.                                       REALS: (         R: REAL);
  2579.                                       BOOLS: (         B: BOOLEAN);
  2580.                                       CHARS: (         C: CHAR)
  2581.                                   END;
  2582.  
  2583.     BEGIN (* INTERPRET *)
  2584.       S[1].I := 0;
  2585.       S[2].I := 0;
  2586.       S[3].I := - 1;
  2587.       S[4].I := BTAB[1].LAST;
  2588.       B := 0;
  2589.       DISPLAY[1] := 0;
  2590.       T := BTAB[2].VSIZE - 1;
  2591.       PC := TAB[S[4].I].ADR;
  2592.       PS := RUN;
  2593.       LNCNT := 0;
  2594.       OCNT := 0;
  2595.       CHRCNT := 0;
  2596.       FLD[1] := 10;
  2597.       FLD[2] := 22;
  2598.       FLD[3] := 10;
  2599.       FLD[4] := 1;
  2600.       REPEAT
  2601.         IR := CODE[PC];
  2602.         PC := PC + 1;
  2603.         OCNT := OCNT + 1;
  2604.         CASE IR.F OF
  2605.           0:
  2606.             BEGIN (* LOAD ADDRESS *)
  2607.               T := T + 1;
  2608.               IF T > STACKSIZE
  2609.               THEN
  2610.                 PS := STKCHK
  2611.               ELSE
  2612.                 S[T].I := DISPLAY[IR.X] + IR.Y
  2613.             END (*0*);
  2614.           1:
  2615.             BEGIN (* LOAD VALUE *)
  2616.               T := T + 1;
  2617.               IF T > STACKSIZE
  2618.               THEN
  2619.                 PS := STKCHK
  2620.               ELSE
  2621.                 S[T] := S[DISPLAY[IR.X] + IR.Y]
  2622.             END (*1*);
  2623.           2:
  2624.             BEGIN (* LOAD INDIRECT *)
  2625.               T := T + 1;
  2626.               IF T > STACKSIZE
  2627.               THEN
  2628.                 PS := STKCHK
  2629.               ELSE
  2630.                 S[T] := S[S[DISPLAY[IR.X] + IR.Y].I]
  2631.             END (*2*);
  2632.           3:
  2633.             BEGIN (* UPDATE DISPLAY *)
  2634.               H1 := IR.Y;
  2635.               H2 := IR.X;
  2636.               H3 := B;
  2637.               REPEAT
  2638.                 DISPLAY[H1] := H3;
  2639.                 H1 := H1 - 1;
  2640.                 H3 := S[H3 + 2].I
  2641.               UNTIL H1 = H2
  2642.             END (*3*);
  2643.           8:
  2644.             CASE IR.Y OF
  2645.               0:
  2646.                 S[T].I := ABS(S[T].I);
  2647.               1:
  2648.                 S[T].R := ABS(S[T].R);
  2649.               2:
  2650.                 S[T].I := SQR(S[T].I);
  2651.               3:
  2652.                 S[T].R := SQR(S[T].R);
  2653.               4:
  2654.                 S[T].B := ODD(S[T].I);
  2655.               5:
  2656.                 BEGIN (* S[T].C := CHR(S[T].I); *)
  2657.                   IF (S[T].I < 0) OR (S[T].I > 63) THEN
  2658.                     PS := INXCHK
  2659.                 END (*5*);
  2660.               6: (* S[T].I:=ORD(S[T].C) *);
  2661.               7:
  2662.                 S[T].C := SUCC(S[T].C);
  2663.               8:
  2664.                 S[T].C := PRED(S[T].C);
  2665.               9:
  2666.                 S[T].I := ROUND(S[T].R);
  2667.               10:
  2668.                 S[T].I := TRUNC(S[T].R);
  2669.               11:
  2670.                 S[T].R := SIN(S[T].R);
  2671.               12:
  2672.                 S[T].R := COS(S[T].R);
  2673.               13:
  2674.                 S[T].R := EXP(S[T].R);
  2675.               14:
  2676.                 S[T].R := LN(S[T].R);
  2677.               15:
  2678.                 S[T].R := SQRT(S[T].R);
  2679.               16:
  2680.                 S[T].R := ARCTAN(S[T].R);
  2681.               17:
  2682.                 BEGIN
  2683.                   T := T + 1;
  2684.                   IF T > STACKSIZE
  2685.                   THEN
  2686.                     PS := STKCHK
  2687.                   ELSE
  2688.                     S[T].B := EOF(INPUT)
  2689.                 END (*17*);
  2690.               18:
  2691.                 BEGIN
  2692.                   T := T + 1;
  2693.                   IF T > STACKSIZE
  2694.                   THEN
  2695.                     PS := STKCHK
  2696.                   ELSE
  2697.                     S[T].B := EOLN(INPUT)
  2698.                 END (*18*);
  2699.             END (*CASE*);
  2700.           9:
  2701.             S[T].I := S[T].I + IR.Y (* OFFSET *);
  2702.           10:
  2703.             PC := IR.Y (* JUMP *);
  2704.           11:
  2705.             BEGIN (* CONDITIONAL JUMP *)
  2706.               IF NOT S[T].B THEN
  2707.                 PC := IR.Y;
  2708.               T := T - 1
  2709.             END (*11*);
  2710.           12:
  2711.             BEGIN (* SWITCH *)
  2712.               H1 := S[T].I;
  2713.               T := T - 1;
  2714.               H2 := IR.Y;
  2715.               H3 := 0;
  2716.               REPEAT
  2717.                 IF CODE[H2].F <> 13
  2718.                 THEN
  2719.                   BEGIN
  2720.                     H3 := 1;
  2721.                     PS := CASCHK
  2722.                   END (*IF*)
  2723.                 ELSE
  2724.                   IF CODE[H2].Y = H1
  2725.                   THEN
  2726.                     BEGIN
  2727.                       H3 := 1;
  2728.                       PC := CODE[H2 + 1].Y
  2729.                     END (*IF*)
  2730.                   ELSE
  2731.                     H2 := H2 + 2
  2732.               UNTIL H3 <> 0;
  2733.             END (*12*);
  2734.           14:
  2735.             BEGIN (* FOR1UP*)
  2736.               H1 := S[T - 1].I;
  2737.               IF H1 <= S[T].I
  2738.               THEN
  2739.                 S[S[T - 2].I].I := H1
  2740.               ELSE
  2741.                 BEGIN
  2742.                   T := T - 3;
  2743.                   PC := IR.Y
  2744.                 END (*ELSE*)
  2745.             END (*14*);
  2746.           15:
  2747.             BEGIN (* FOR2UP *)
  2748.               H2 := S[T - 2].I;
  2749.               H1 := S[H2].I + 1;
  2750.               IF H1 <= S[T].I
  2751.               THEN
  2752.                 BEGIN
  2753.                   S[H2].I := H1;
  2754.                   PC := IR.Y
  2755.                 END (*IF*)
  2756.               ELSE
  2757.                 T := T - 3;
  2758.             END (*15*);
  2759.           16:
  2760.             BEGIN (*FOR1DOWN*)
  2761.               H1 := S[T - 1].I;
  2762.               IF H1 >= S[T].I
  2763.               THEN
  2764.                 S[S[T - 2].I].I := H1
  2765.               ELSE
  2766.                 BEGIN
  2767.                   PC := IR.Y;
  2768.                   T := T - 3;
  2769.                 END (*ELSE*)
  2770.             END (*16*);
  2771.           17:
  2772.             BEGIN (*FOR2DOWN*)
  2773.               H2 := S[T - 2].I;
  2774.               H1 := S[H2].I - 1;
  2775.               IF H1 >= S[T].I
  2776.               THEN
  2777.                 BEGIN
  2778.                   S[H2].I := H1;
  2779.                   PC := IR.Y
  2780.                 END (*IF*)
  2781.               ELSE
  2782.                 T := T - 3
  2783.             END (*17*);
  2784.           18:
  2785.             BEGIN (* MARCK STACK*)
  2786.               H1 := BTAB[TAB[IR.Y].IREF].VSIZE;
  2787.               IF T + H1 > STACKSIZE
  2788.               THEN
  2789.                 PS := STKCHK
  2790.               ELSE
  2791.                 BEGIN
  2792.                   T := T + 5;
  2793.                   S[T - 1].I := H1 - 1;
  2794.                   S[T].I := IR.Y
  2795.                 END (*ELSE*)
  2796.             END (*18*);
  2797.           19:
  2798.             BEGIN (* CALL *)
  2799.               H1 := T - IR.Y (*H1 POINTS TO BASE *);
  2800.               H2 := S[H1 + 4].I (*H2 POINTS TO TAB *);
  2801.               H3 := TAB[H2].LEV;
  2802.               DISPLAY[H3 + 1] := H1;
  2803.               H4 := S[H1 + 3].I + H1;
  2804.               S[H1 + 1].I := PC;
  2805.               S[H1 + 2].I := DISPLAY[H3];
  2806.               S[H1 + 3].I := B;
  2807.               FOR H3 := T + 1 TO H4 DO
  2808.                 S[H3].I := 0;
  2809.               B := H1;
  2810.               T := H4;
  2811.               PC := TAB[H2].ADR
  2812.             END (*19*);
  2813.           20:
  2814.             BEGIN (* INDEX1 *)
  2815.               H1 := IR.Y (* H1 POINTS TO ATAB *);
  2816.               H2 := ATAB[H1].LOW;
  2817.               H3 := S[T].I;
  2818.               IF H3 < H2
  2819.               THEN
  2820.                 PS := INXCHK
  2821.               ELSE
  2822.                 IF H3 > ATAB[H1].HIGH
  2823.                 THEN
  2824.                   PS := INXCHK
  2825.                 ELSE
  2826.                   BEGIN
  2827.                     T := T - 1;
  2828.                     S[T].I := S[T].I + (H3 - H2)
  2829.                   END (*ELSE*)
  2830.             END (*20*);
  2831.           21:
  2832.             BEGIN (* INDEX *)
  2833.               H1 := IR.Y (* H1 POINTS TO ATAB *);
  2834.               H2 := ATAB[H1].LOW;
  2835.               H3 := S[T].I;
  2836.               IF H3 < H2
  2837.               THEN
  2838.                 PS := INXCHK
  2839.               ELSE
  2840.                 IF H3 > ATAB[H1].HIGH
  2841.                 THEN
  2842.                   PS := INXCHK
  2843.                 ELSE
  2844.                   BEGIN
  2845.                     T := T - 1;
  2846.                     S[T].I := S[T].I + (H3 - H2) * ATAB[H1].ELSIZE
  2847.                   END (*ELSE*)
  2848.             END (*21*);
  2849.           22:
  2850.             BEGIN (* LOAD BLOCK *)
  2851.               H1 := S[T].I;
  2852.               T := T - 1;
  2853.               H2 := IR.Y + T;
  2854.               IF H2 > STACKSIZE
  2855.               THEN
  2856.                 PS := STKCHK
  2857.               ELSE
  2858.                 WHILE T < H2 DO
  2859.                   BEGIN
  2860.                     T := T + 1;
  2861.                     S[T] := S[H1];
  2862.                     H1 := H1 + 1
  2863.                   END (*WHILE*)
  2864.             END (*22*);
  2865.           23:
  2866.             BEGIN (* COPY BLOCK *)
  2867.               H1 := S[T - 1].I;
  2868.               H2 := S[T].I;
  2869.               H3 := H1 + IR.Y;
  2870.               WHILE H1 < H3 DO
  2871.                 BEGIN
  2872.                   S[H1] := S[H2];
  2873.                   H1 := H1 + 1;
  2874.                   H2 := H2 + 1
  2875.                 END (*WHILE*);
  2876.               T := T - 2
  2877.             END (*23*);
  2878.           24:
  2879.             BEGIN (* LITERAL *)
  2880.               T := T - 1;
  2881.               IF T > STACKSIZE
  2882.               THEN
  2883.                 PS := STKCHK
  2884.               ELSE
  2885.                 S[T].I := IR.Y
  2886.             END (*24*);
  2887.           25:
  2888.             BEGIN (* LOAD REAL *)
  2889.               T := T - 1;
  2890.               IF T > STACKSIZE
  2891.               THEN
  2892.                 PS := STKCHK
  2893.               ELSE
  2894.                 S[T].R := RCONST[IR.Y]
  2895.             END (*25*);
  2896.           26:
  2897.             BEGIN (* FLOAT *)
  2898.               H1 := T - IR.Y;
  2899.               S[H1].R := S[H1].I;
  2900.             END (*26*);
  2901.           27:
  2902.             BEGIN (* READ *)
  2903.               IF EOF(INPUT)
  2904.               THEN
  2905.                 PS := REDCHK
  2906.               ELSE
  2907.                 CASE IR.Y OF
  2908.                   1:
  2909.                     READ(S[S[T].I].I);
  2910.                   2:
  2911.                     READ(S[S[T].I].R);
  2912.                   3:
  2913.                     READ(S[S[T].I].C);
  2914.                 END (*CASE*);
  2915.               T := T - 1
  2916.             END (*27*);
  2917.           28:
  2918.             BEGIN (* WRITE STRING *)
  2919.               H1 := S[T].I;
  2920.               H2 := IR.Y;
  2921.               T := T - 1;
  2922.               CHRCNT := CHRCNT + H1;
  2923.               IF CHRCNT > LINELENG THEN
  2924.                 PS := LNGCHK;
  2925.               REPEAT
  2926.                 WRITE(STAB[H2]);
  2927.                 H1 := H1 - 1;
  2928.                 H2 := H2 + 1
  2929.               UNTIL H1 = 0
  2930.             END (*28*);
  2931.           29:
  2932.             BEGIN (* WRITE1 *)
  2933.               CHRCNT := CHRCNT + FLD[IR.Y];
  2934.               IF CHRCNT > LINELENG
  2935.               THEN
  2936.                 PS := LNGCHK
  2937.               ELSE
  2938.                 CASE IR.Y OF
  2939.                   1:
  2940.                     WRITE(S[T].I: FLD[1]);
  2941.                   2:
  2942.                     WRITE(S[T].R: FLD[2]);
  2943.                   3:
  2944.                     WRITE(S[T].B: FLD[3]);
  2945.                   4:
  2946.                     WRITE(S[T].C)
  2947.                 END (*CASE*);
  2948.               T := T - 1
  2949.             END (*29*);
  2950.           30:
  2951.             BEGIN (* WRITE2 *)
  2952.               CHRCNT := CHRCNT + S[T].I;
  2953.               IF CHRCNT > LINELENG
  2954.               THEN
  2955.                 PS := LNGCHK
  2956.               ELSE
  2957.                 CASE IR.Y OF
  2958.                   1:
  2959.                     WRITE(S[T - 1].I: S[T].I);
  2960.                   2:
  2961.                     WRITE(S[T - 1].R: S[T].I);
  2962.                   3:
  2963.                     WRITE(S[T - 1].B: S[T].I);
  2964.                   4:
  2965.                     WRITE(S[T - 1].C: S[T].I);
  2966.                 END (*CASE*);
  2967.               T := T - 2
  2968.             END (*30*);
  2969.           31:
  2970.             PS := FIN;
  2971.           32:
  2972.             BEGIN (* EXIT PROCEDURE *)
  2973.               T := B - 1;
  2974.               PC := S[B + 1].I;
  2975.               B := S[B + 3].I
  2976.             END (*32*);
  2977.           33:
  2978.             BEGIN (* EXIT FUNCTION *)
  2979.               T := B;
  2980.               PC := S[B + 1].I;
  2981.               B := S[B + 3].I
  2982.             END (*33*);
  2983.           34:
  2984.             S[T] := S[S[T].I];
  2985.           35:
  2986.             S[T].B := NOT S[T].B;
  2987.           36:
  2988.             S[T].I := - S[T].I;
  2989.           37:
  2990.             BEGIN
  2991.               CHRCNT := CHRCNT + S[T - 1].I;
  2992.               IF CHRCNT > LINELENG
  2993.               THEN
  2994.                 PS := LNGCHK
  2995.               ELSE
  2996.                 WRITE(S[T - 2].R: S[T - 1].I: S[T].I);
  2997.               T := T - 3
  2998.             END (*37*);
  2999.           38:
  3000.             BEGIN (* STORE *)
  3001.               S[S[T - 1].I] := S[T];
  3002.               T := T - 2
  3003.             END (*38*);
  3004.           39:
  3005.             BEGIN
  3006.               T := T - 1;
  3007.               S[T].B := S[T].R = S[T + 1].R
  3008.             END (*39*);
  3009.           40:
  3010.             BEGIN
  3011.               T := T - 1;
  3012.               S[T].B := S[T].R <> S[T + 1].R
  3013.             END (*40*);
  3014.           41:
  3015.             BEGIN
  3016.               T := T - 1;
  3017.               S[T].B := S[T].R < S[T + 1].R
  3018.             END (*41*);
  3019.           42:
  3020.             BEGIN
  3021.               T := T - 1;
  3022.               S[T].B := S[T].R <= S[T + 1].R
  3023.             END (*42*);
  3024.           43:
  3025.             BEGIN
  3026.               T := T - 1;
  3027.               S[T].B := S[T].R > S[T + 1].R
  3028.             END (*43*);
  3029.           44:
  3030.             BEGIN
  3031.               T := T - 1;
  3032.               S[T].B := S[T].R >= S[T + 1].R
  3033.             END (*44*);
  3034.           45:
  3035.             BEGIN
  3036.               T := T - 1;
  3037.               S[T].B := S[T].I = S[T + 1].I
  3038.             END (*45*);
  3039.           46:
  3040.             BEGIN
  3041.               T := T - 1;
  3042.               S[T].B := S[T].I <> S[T + 1].I
  3043.             END (*46*);
  3044.           47:
  3045.             BEGIN
  3046.               T := T - 1;
  3047.               S[T].B := S[T].I < S[T + 1].I
  3048.             END (*47*);
  3049.           48:
  3050.             BEGIN
  3051.               T := T - 1;
  3052.               S[T].B := S[T].I <= S[T + 1].I
  3053.             END (*48*);
  3054.           49:
  3055.             BEGIN
  3056.               T := T - 1;
  3057.               S[T].B := S[T].I > S[T + 1].I
  3058.             END (*49*);
  3059.           50:
  3060.             BEGIN
  3061.               T := T - 1;
  3062.               S[T].B := S[T].I >= S[T + 1].I
  3063.             END (*50*);
  3064.           51:
  3065.             BEGIN
  3066.               T := T - 1;
  3067.               S[T].B := S[T].B OR S[T + 1].B
  3068.             END (*51*);
  3069.           52:
  3070.             BEGIN
  3071.               T := T - 1;
  3072.               S[T].I := S[T].I + S[T + 1].I
  3073.             END (*52*);
  3074.           53:
  3075.             BEGIN
  3076.               T := T - 1;
  3077.               S[T].I := S[T].I - S[T + 1].I
  3078.             END (*53*);
  3079.           54:
  3080.             BEGIN
  3081.               T := T - 1;
  3082.               S[T].R := S[T].R + S[T + 1].R
  3083.             END (*54*);
  3084.           55:
  3085.             BEGIN
  3086.               T := T - 1;
  3087.               S[T].R := S[T].R - S[T + 1].R
  3088.             END (*55*);
  3089.           56:
  3090.             BEGIN
  3091.               T := T - 1;
  3092.               S[T].B := S[T].B AND S[T + 1].B
  3093.             END (*56*);
  3094.           57:
  3095.             BEGIN
  3096.               T := T - 1;
  3097.               S[T].I := S[T].I * S[T + 1].I
  3098.             END (*57*);
  3099.           58:
  3100.             BEGIN
  3101.               T := T - 1;
  3102.               IF S[T + 1].I = 0
  3103.               THEN
  3104.                 PS := DIVCHK
  3105.               ELSE
  3106.                 S[T].I := S[T].I DIV S[T + 1].I
  3107.             END (*58*);
  3108.           59:
  3109.             BEGIN
  3110.               T := T - 1;
  3111.               IF S[T + 1].I = 0
  3112.               THEN
  3113.                 PS := DIVCHK
  3114.               ELSE
  3115.                 S[T].I := S[T].I MOD S[T + 1].I
  3116.             END (*59*);
  3117.           60:
  3118.             BEGIN
  3119.               T := T - 1;
  3120.               S[T].R := S[T].R * S[T + 1].R
  3121.             END (*60*);
  3122.           61:
  3123.             BEGIN
  3124.               T := T - 1;
  3125.               S[T].R := S[T].R / S[T + 1].R
  3126.             END (*61*);
  3127.           62:
  3128.             IF EOF(INPUT)
  3129.             THEN
  3130.               PS := REDCHK
  3131.             ELSE
  3132.               READLN;
  3133.           63:
  3134.             BEGIN
  3135.               WRITELN;
  3136.               LNCNT := LNCNT + 1;
  3137.               CHRCNT := 0;
  3138.               IF LNCNT > LINELIMIT THEN
  3139.                 PS := LINCHK
  3140.             END (*63*)
  3141.         END (* CASE *);
  3142.       UNTIL PS <> RUN;
  3143.       IF PS <> FIN
  3144.       THEN
  3145.         BEGIN
  3146.           WRITELN;
  3147.           WRITE('0HALT AT ', PC: 5, ' BECAUSE OF ');
  3148.           CASE PS OF
  3149.             CASCHK:
  3150.               WRITELN('UNDEFINED CASE');
  3151.             DIVCHK:
  3152.               WRITELN('DIVISION BY 0');
  3153.             INXCHK:
  3154.               WRITELN('STORAGE OVERFLOW');
  3155.             LINCHK:
  3156.               WRITELN('TOO MUCH OUTPUT');
  3157.             LNGCHK:
  3158.               WRITELN('LINE TOO LONG');
  3159.             REDCHK:
  3160.               WRITELN('READING PAST END OF FILE');
  3161.           END (*CASE*);
  3162.           H1 := B;
  3163.           BLKCNT := 10 (* POST MORTEM DUMP *);
  3164.           REPEAT
  3165.             WRITELN;
  3166.             BLKCNT := BLKCNT - 1;
  3167.             IF BLKCNT = 0 THEN
  3168.               H1 := 0;
  3169.             H2 := S[H1 + 4].I;
  3170.             IF H1 <> 0 THEN
  3171.               WRITELN(' ', TAB[H2].NAME, '  CALLED AT', S[H1 + 1].I: 5);
  3172.             H2 := BTAB[TAB[H2].IREF].LAST;
  3173.             WHILE H2 <> 0 DO
  3174.               WITH TAB[H2] DO
  3175.                 BEGIN
  3176.                   IF OBJ = VARIABLE
  3177.                   THEN
  3178.                     IF TYP IN STANTYPS
  3179.                     THEN
  3180.                       BEGIN
  3181.                         WRITE('    ', NAME, ' = ');
  3182.                         IF NORMAL
  3183.                         THEN
  3184.                           H3 := H1 + ADR
  3185.                         ELSE
  3186.                           H3 := S[H1 + ADR].I;
  3187.                         CASE TYP OF
  3188.                           INTS:
  3189.                             WRITELN(S[H3].I);
  3190.                           REALS:
  3191.                             WRITELN(S[H3].R);
  3192.                           BOOLS:
  3193.                             WRITELN(S[H3].B);
  3194.                           CHARS:
  3195.                             WRITELN(S[H3].C);
  3196.                         END (*CASE*)
  3197.                       END (*IF*);
  3198.                   H2 := LINK
  3199.                 END (*WITH*);
  3200.             H1 := S[H1 + 3].I
  3201.           UNTIL H1 < 0;
  3202.         END (*IF*);
  3203.       WRITELN;
  3204.       WRITELN(OCNT, ' STEPS')
  3205.     END (*INTERPRET*);
  3206.  
  3207.  
  3208.   BEGIN (* MAIN PROGRAM *)
  3209.     WRITELN;
  3210.     KEY[1] := 'AND       ';
  3211.     KEY[2] := 'ARRAY     ';
  3212.     KEY[3] := 'BEGIN     ';
  3213.     KEY[4] := 'CASE      ';
  3214.     KEY[5] := 'CONST     ';
  3215.     KEY[6] := 'DIV       ';
  3216.     KEY[7] := 'DOWNTO    ';
  3217.     KEY[8] := 'DO        ';
  3218.     KEY[9] := 'ELSE      ';
  3219.     KEY[10] := 'END       ';
  3220.     KEY[11] := 'FOR       ';
  3221.     KEY[12] := 'FUNCTION  ';
  3222.     KEY[13] := 'IF        ';
  3223.     KEY[14] := 'MOD       ';
  3224.     KEY[15] := 'NOT       ';
  3225.     KEY[16] := 'OF        ';
  3226.     KEY[17] := 'OR        ';
  3227.     KEY[18] := 'PROCEDURE ';
  3228.     KEY[19] := 'PROGRAM   ';
  3229.     KEY[20] := 'RECORD    ';
  3230.     KEY[21] := 'REPEAT    ';
  3231.     KEY[22] := 'THEN      ';
  3232.     KEY[23] := 'TO        ';
  3233.     KEY[24] := 'TYPE      ';
  3234.     KEY[25] := 'UNTIL     ';
  3235.     KEY[26] := 'VAR       ';
  3236.     KEY[27] := 'WHILE     ';
  3237.     KSY[1] := ANDSY;
  3238.     KSY[2] := ARRAYSY;
  3239.     KSY[3] := BEGINSY;
  3240.     KSY[4] := CASESY;
  3241.     KSY[5] := CONSTSY;
  3242.     KSY[6] := IDIV;
  3243.     KSY[7] := DOWNTOSY;
  3244.     KSY[8] := DOSY;
  3245.     KSY[9] := ELSESY;
  3246.     KSY[10] := ENDSY;
  3247.     KSY[11] := FORSY;
  3248.     KSY[12] := FUNCTIONSY;
  3249.     KSY[13] := IFSY;
  3250.     KSY[14] := IMOD;
  3251.     KSY[15] := NOTSY;
  3252.     KSY[16] := OFSY;
  3253.     KSY[17] := ORSY;
  3254.     KSY[18] := PROCEDURESY;
  3255.     KSY[19] := PROGRAMSY;
  3256.     KSY[20] := RECORDSY;
  3257.     KSY[21] := REPEATSY;
  3258.     KSY[22] := THENSY;
  3259.     KSY[23] := TOSY;
  3260.     KSY[24] := TYPESY;
  3261.     KSY[25] := UNTILSY;
  3262.     KSY[26] := VARSY;
  3263.     KSY[27] := WHILESY;
  3264.     SPS['+'] := PLUS;
  3265.     SPS['-'] := MINUS;
  3266.     SPS['*'] := TIMES;
  3267.     SPS['/'] := RDIV;
  3268.     SPS['='] := EQL;
  3269.     SPS['['] := LBRACK;
  3270.     SPS[']'] := RBRACK;
  3271.     SPS['&'] := ANDSY;
  3272.     SPS['('] := LPARENT;
  3273.     SPS[')'] := RPARENT;
  3274.     SPS[','] := COMMA;
  3275.     SPS['#'] := NEQ;
  3276.     SPS[';'] := SEMICOLON;
  3277.     CONSTBEGSYS := [PLUS, MINUS, INTCON, REALCON, CHARCON, IDENT];
  3278.     TYPEBEGSYS := [IDENT, ARRAYSY, RECORDSY];
  3279.     BLOCKBEGSYS := [CONSTSY, TYPESY, VARSY, PROCEDURESY, FUNCTIONSY, BEGINSY];
  3280.     FACBEGSYS := [INTCON, REALCON, CHARCON, IDENT, LPARENT, NOTSY];
  3281.     STATBEGSYS := [BEGINSY, IFSY, WHILESY, REPEATSY, FORSY, CASESY];
  3282.     STANTYPS := [NOTYP, INTS, REALS, BOOLS, CHARS];
  3283.     LC := 0;
  3284.     LL := 0;
  3285.     CC := 0;
  3286.     CH := ' ';
  3287.     ERRPOS := 0;
  3288.     ERRS := [];
  3289.     INSYMBOL;
  3290.     T := - 1;
  3291.     A := 0;
  3292.     B := 1;
  3293.     SX := 0;
  3294.     C2 := 0;
  3295.     DISPLAY[0] := 1;
  3296.     IFLAG := FALSE;
  3297.     OFLAG := FALSE;
  3298.     IF SY <> PROGRAMSY
  3299.     THEN
  3300.       ERROR(3)
  3301.     ELSE
  3302.       BEGIN
  3303.         INSYMBOL;
  3304.         IF SY <> IDENT
  3305.         THEN
  3306.           ERROR(2)
  3307.         ELSE
  3308.           BEGIN
  3309.             PROGNAME := ID;
  3310.             INSYMBOL;
  3311.             IF SY <> LPARENT
  3312.             THEN
  3313.               ERROR(9)
  3314.             ELSE
  3315.               REPEAT
  3316.                 INSYMBOL;
  3317.                 IF SY <> IDENT
  3318.                 THEN
  3319.                   ERROR(2)
  3320.                 ELSE
  3321.                   BEGIN
  3322.                     IF ID = 'INPUT     '
  3323.                     THEN
  3324.                       IFLAG := TRUE
  3325.                     ELSE
  3326.                       IF ID = 'OUTPUT    '
  3327.                       THEN
  3328.                         OFLAG := TRUE
  3329.                       ELSE
  3330.                         ERROR(0);
  3331.                     INSYMBOL
  3332.                   END (*ELSE*)
  3333.               UNTIL SY <> COMMA;
  3334.             IF SY = RPARENT
  3335.             THEN
  3336.               INSYMBOL
  3337.             ELSE
  3338.               ERROR(4);
  3339.             IF NOT OFLAG THEN
  3340.               ERROR(20)
  3341.           END (*ELSE*)
  3342.       END (*ELSE*);
  3343.     ENTER('          ', VARIABLE, NOTYP, 0);
  3344.     ENTER('FALSE     ', KONSTANT, BOOLS, 0);
  3345.     ENTER('TRUE      ', KONSTANT, BOOLS, 1);
  3346.     ENTER('REAL      ', TYPE1, REALS, 1);
  3347.     ENTER('CHAR      ', TYPE1, CHARS, 1);
  3348.     ENTER('BOOLEAN   ', TYPE1, BOOLS, 1);
  3349.     ENTER('INTEGER   ', TYPE1, INTS, 1);
  3350.     ENTER('ABS       ', FUNKTION, REALS, 0);
  3351.     ENTER('SQR       ', FUNKTION, REALS, 2);
  3352.     ENTER('ODD       ', FUNKTION, BOOLS, 4);
  3353.     ENTER('CHR       ', FUNKTION, CHARS, 5);
  3354.     ENTER('ORD       ', FUNKTION, INTS, 6);
  3355.     ENTER('SUCC      ', FUNKTION, CHARS, 7);
  3356.     ENTER('PRED      ', FUNKTION, CHARS, 8);
  3357.     ENTER('ROUND     ', FUNKTION, INTS, 9);
  3358.     ENTER('TRUNC     ', FUNKTION, INTS, 10);
  3359.     ENTER('SIN       ', FUNKTION, REALS, 11);
  3360.     ENTER('COS       ', FUNKTION, REALS, 12);
  3361.     ENTER('EXP       ', FUNKTION, REALS, 13);
  3362.     ENTER('LN        ', FUNKTION, REALS, 14);
  3363.     ENTER('SQRT      ', FUNKTION, REALS, 15);
  3364.     ENTER('ARCTAN    ', FUNKTION, REALS, 16);
  3365.     ENTER('EOF       ', FUNKTION, BOOLS, 17);
  3366.     ENTER('EOLN      ', FUNKTION, BOOLS, 18);
  3367.     ENTER('READ      ', PROZEDURE, NOTYP, 1);
  3368.     ENTER('READLN    ', PROZEDURE, NOTYP, 2);
  3369.     ENTER('WRITE     ', PROZEDURE, NOTYP, 3);
  3370.     ENTER('WRITELN   ', PROZEDURE, NOTYP, 4);
  3371.     ENTER('          ', PROZEDURE, NOTYP, 0);
  3372.     WITH BTAB[1] DO
  3373.       BEGIN
  3374.         LAST := T;
  3375.         LASTPAR := 1;
  3376.         PSIZE := 0;
  3377.         VSIZE := 0
  3378.       END (*WITH*);
  3379.     BLOCK(BLOCKBEGSYS + STATBEGSYS, FALSE, 1);
  3380.     IF SY <> PERIOD THEN
  3381.       ERROR(22);
  3382.     EMIT(31) (* HALT *);
  3383.     IF BTAB[2].VSIZE > STACKSIZE THEN
  3384.       ERROR(49);
  3385.     IF PROGNAME = 'TEST0     ' THEN
  3386.       PRINTTABLES;
  3387.     IF ERRS = []
  3388.     THEN
  3389.       BEGIN
  3390.         IF IFLAG
  3391.         THEN
  3392.           BEGIN
  3393.             IF EOF(INPUT)
  3394.             THEN
  3395.               WRITELN(' INPUT DATA MISSING')
  3396.             ELSE
  3397.               BEGIN
  3398.                 WRITELN(' (EOR) ') (* COPY INPUT DATA *);
  3399.                 WHILE NOT EOF(INPUT) DO
  3400.                   BEGIN
  3401.                     WRITE(' ');
  3402.                     WHILE NOT EOLN(INPUT) DO
  3403.                       BEGIN
  3404.                         READ(CH);
  3405.                         WRITE(CH);
  3406.                       END (*WHILE*);
  3407.                     WRITELN;
  3408.                     READ(CH)
  3409.                   END (*WHILE*);
  3410.               END (*ELSE*)
  3411.           END (*IF*);
  3412.         WRITELN(' (EOF) ');
  3413.         INTERPRET
  3414.       END (*IF*)
  3415.     ELSE
  3416.       ERRORMSG;
  3417. 99:
  3418.   END (*PASCALS*).
  3419.